Estoy buscando una clase que puede dar salida a un objeto y todos sus valores hoja en un formato similar a este:

User
  - Name: Gordon
  - Age : 60
  - WorkAddress
     - Street: 10 Downing Street
     - Town: London
     - Country: UK
  - HomeAddresses[0]
    ...
  - HomeAddresses[1]
    ...

(O una más clara de formato). Esto sería equivalente a:

public class User
{
    public string Name { get;set; }
    public int Age { get;set; }
    public Address WorkAddress { get;set; }
    public List<Address> HomeAddresses { get;set; }
}

public class Address
{
    public string Street { get;set; }
    public string Town { get;set; }
    public string Country { get;set; }
}

Una especie de representación de cadena de la PropertyGrid control, menos tener que implementar un conjunto de grandes diseñadores para cada tipo.

PHP tiene algo que hace esto se llama var_dump. No quiero usar un reloj, ya que esto es para imprimir.

Podría alguien me apunte a algo como esto, si es que existe? O, escribir uno para una recompensa.

InformationsquelleAutor Chris S | 2009-08-28

12 Comentarios

  1. 51

    El objeto dumper publicado en sgmoore link:

    //Copyright (C) Microsoft Corporation.  All rights reserved.
    using System;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    //See the ReadMe.html for additional information
    public class ObjectDumper {
    public static void Write(object element)
    {
    Write(element, 0);
    }
    public static void Write(object element, int depth)
    {
    Write(element, depth, Console.Out);
    }
    public static void Write(object element, int depth, TextWriter log)
    {
    ObjectDumper dumper = new ObjectDumper(depth);
    dumper.writer = log;
    dumper.WriteObject(null, element);
    }
    TextWriter writer;
    int pos;
    int level;
    int depth;
    private ObjectDumper(int depth)
    {
    this.depth = depth;
    }
    private void Write(string s)
    {
    if (s != null) {
    writer.Write(s);
    pos += s.Length;
    }
    }
    private void WriteIndent()
    {
    for (int i = 0; i < level; i++) writer.Write("  ");
    }
    private void WriteLine()
    {
    writer.WriteLine();
    pos = 0;
    }
    private void WriteTab()
    {
    Write("  ");
    while (pos % 8 != 0) Write(" ");
    }
    private void WriteObject(string prefix, object element)
    {
    if (element == null || element is ValueType || element is string) {
    WriteIndent();
    Write(prefix);
    WriteValue(element);
    WriteLine();
    }
    else {
    IEnumerable enumerableElement = element as IEnumerable;
    if (enumerableElement != null) {
    foreach (object item in enumerableElement) {
    if (item is IEnumerable && !(item is string)) {
    WriteIndent();
    Write(prefix);
    Write("...");
    WriteLine();
    if (level < depth) {
    level++;
    WriteObject(prefix, item);
    level--;
    }
    }
    else {
    WriteObject(prefix, item);
    }
    }
    }
    else {
    MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
    WriteIndent();
    Write(prefix);
    bool propWritten = false;
    foreach (MemberInfo m in members) {
    FieldInfo f = m as FieldInfo;
    PropertyInfo p = m as PropertyInfo;
    if (f != null || p != null) {
    if (propWritten) {
    WriteTab();
    }
    else {
    propWritten = true;
    }
    Write(m.Name);
    Write("=");
    Type t = f != null ? f.FieldType : p.PropertyType;
    if (t.IsValueType || t == typeof(string)) {
    WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null));
    }
    else {
    if (typeof(IEnumerable).IsAssignableFrom(t)) {
    Write("...");
    }
    else {
    Write("{ }");
    }
    }
    }
    }
    if (propWritten) WriteLine();
    if (level < depth) {
    foreach (MemberInfo m in members) {
    FieldInfo f = m as FieldInfo;
    PropertyInfo p = m as PropertyInfo;
    if (f != null || p != null) {
    Type t = f != null ? f.FieldType : p.PropertyType;
    if (!(t.IsValueType || t == typeof(string))) {
    object value = f != null ? f.GetValue(element) : p.GetValue(element, null);
    if (value != null) {
    level++;
    WriteObject(m.Name + ": ", value);
    level--;
    }
    }
    }
    }
    }
    }
    }
    }
    private void WriteValue(object o)
    {
    if (o == null) {
    Write("null");
    }
    else if (o is DateTime) {
    Write(((DateTime)o).ToShortDateString());
    }
    else if (o is ValueType || o is string) {
    Write(o.ToString());
    }
    else if (o is IEnumerable) {
    Write("...");
    }
    else {
    Write("{ }");
    }
    }
    }

    2015 Actualización

    YAML también sirve para este propósito bastante bien, esta es la forma en que se puede hacer con YamlDotNet

    install-package YamlDotNet

        private static void DumpAsYaml(object o)
    {
    var stringBuilder = new StringBuilder();
    var serializer = new Serializer();
    serializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), o);
    Console.WriteLine(stringBuilder);
    }
    • Sería grandioso si hubiera una manera para deserializar esta en un objeto. 🙂
    • ObjectDumper no muestra contenido de las matrices.
    • En DumpAsYaml() prefería cambiar Console.WriteLine() a Debug.WriteLine() por lo que funciona no sólo en WebForms/Consola (y, probablemente, WTF, no estoy seguro) pero WebForms demasiado. De couse estoy asumiendo que es el modo de depuración (pero quien va a llamar incluso DumpAsYaml() en realse modo)?
    • Upvote de YAML, parece que el formato OP quiere es bastante YAML. Serializador es todo lo que él quiere.
    • //Copyright (C) Microsoft Corporation. Todos los derechos reservados.
    • El dumper no es la manipulación de log4net.Util.SystemStringFormat. O con el registro de cadena de formato no se manejan. log.InfoFormat()

  2. 31

    Podría utilizar el JSON serialiser, que debe ser fácil de leer para cualquier persona que utilice para trabajar con JSON

    User theUser = new User();
    theUser.Name = "Joe";
    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myPerson.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, theUser );
    string json = Encoding.Default.GetString(ms.ToArray()); 
    • Tengo el código que hará que la salida JSON, más fácil de leer (con saltos de línea) aquí stackoverflow.com/questions/5881204/…
    • Esta es la mejor respuesta. ¿Por qué no usar Serialización para el volcado de un objeto? Usted puede simplemente utilizar un JSON en el visor de la sangría, listas de tareas, etc.
    • También una buena alternativa debe ser la utilización de Newtonsoft Json de la biblioteca, que muchos de nosotros ya sabemos y que es realmente fácil de usar. JsonConvert.SerializeObject(items, Formatting.Indented) para el formato de salida. En nuget: nuget.org/packages/Newtonsoft.Json
    • El uso de un JSON serializador es un consejo excelente, y el uso de NewtonSoft JSON para hacerlo es incluso mejor. Muchas gracias!
    • Yo uso el código, pero no por completo, el trabajo, entonces puedo cambiar para ser como este: NameValueCollection nvc = Context.Request.Form; JavaScriptSerializer serializer = new JavaScriptSerializer (); string json = serializer.Serialize (nvc); Context.Response.Write (json);
  3. 13

    Si estás trabajando con marcado, Sistema.Web.ObjectInfo.Imprimir (ASP.NET Páginas Web 2) llevará a cabo, bien con formato HTML.

    Por ejemplo:

    @ObjectInfo.Print(new {
    Foo = "Hello",
    Bar = "World",
    Qux = new {
    Number = 42,
    },
    })

    En una página web, produce:

    objeto dumper clase

    • muy bonito, yo no sabía de
    • ¿Alguna idea de cómo puede ser utilizado con Webforms?
  4. 12

    Aquí una extensión de visual studio escribí para ello:

    https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f

    en acción:
    objeto dumper clase

    • Sería genial si el C# generación de objetos de cosas sería una dll independiente/nuget-paquete para poder utilizarlo en LinqPad para on-the-fly objeto y el código de los vertederos. Después de casi una década .net dev todavía echo de menos el perl Data::Dumper.
    • Esta es una gran extensión de Gracias.
    • Esto parece que está destinado a ser utilizado durante la depuración interactiva — ¿es eso cierto? O puede ser usado en otras formas?
    • eso es correcto, usted necesita ser detenido en un punto de interrupción para exportar el objeto. Similar a como lo haría uso de los locales o la ventana de inspección.
    • no, ya que este se basa en el Entorno de Visual Studio para recuperar los valores no de la reflexión. Ya se puede serializar a formato XML o JSON con bastante facilidad en el código a través de las bibliotecas populares. Estás tratando específicamente serializar un objeto de C# de POCO?
  5. 8

    Sé que esto es una vieja pregunta, pero pensé en tirar una alternativa que trabajó para mí, me tomó alrededor de dos minutos para hacerlo.

    Instalar Newtonsoft Json.NET:
    http://james.newtonking.com/json

    (o nuget versión) http://www.nuget.org/packages/newtonsoft.json/

    Conjunto De Referencia:

    using Newtonsoft.Json;

    Volcado de la cadena JSON para iniciar sesión:

    txtResult.Text = JsonConvert.SerializeObject(testObj);
    • Lo único malo de esta solución es de las enumeraciones se muestran en el formato numérico en lugar de su valor de texto. Una buena solución, aunque de otra manera.
    • Aquí está una camisa con bastante formato y la enumeración de los nombres de: Newtonsoft.Json.JsonConvert.SerializeObject(testObj, Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonSerializerSettings() { Converters = new List<Newtonsoft.Json.JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter() } })
    • Y si usted desea serializar los campos privados, puede anotar en la correspondiente clase(s) con: [JsonObject(MemberSerialization.Fields)]
  6. 7

    Podría escribir muy fácilmente con un poco de reflexión. Algo como:

    public void Print(object value, int depth)
    {
    foreach(var property in value.GetType().GetProperties())
    {
    var subValue = property.GetValue(value);
    if(subValue is IEnumerable)
    {
    PrintArray(property, (IEnumerable)subValue);
    }
    else
    {
    PrintProperty(property, subValue);
    }         
    }
    }

    Puede escribir hasta el PrintArray y PrintProperty métodos.

    • Estoy buscando uno que ya existe
    • Más cercano que he visto es ObjectDumper. Ver esta pregunta stackoverflow.com/questions/360277/…
    • Yo había escrito sobre todo lo que Jakers había, pero pensaba que esta debe existir. Te voy a dar jakers 1 por el esfuerzo (que no se compila, pero eso no es un problema). Parece sgmoore del vínculo que hace que este closeable
    • Tengo un No overload for method 'GetValue' takes 1 arguments con esto..
  7. 7

    Tengo un práctico T. Dump() método de Extensión que debe estar muy cerca de los resultados que usted está buscando. Como un método de extensión, su carácter no invasivo y debería funcionar en todos los objetos POCO.

    Ejemplo De Uso De

    var model = new TestModel();
    Console.WriteLine(model.Dump());

    Ejemplo De Salida

    {
    Int: 1,
    String: One,
    DateTime: 2010-04-11,
    Guid: c050437f6fcd46be9b2d0806a0860b3e,
    EmptyIntList: [],
    IntList:
    [
    1,
    2,
    3
    ],
    StringList:
    [
    one,
    two,
    three
    ],
    StringIntMap:
    {
    a: 1,
    b: 2,
    c: 3
    }
    }
    • +1, excelente. Yo deseaba que este había impreso el nombre de la propiedad demasiado
    • Bueno, pero debe ser más claro que esto es parte de ServiceStack.
  8. 2

    Si usted no se siente como copiar y pegar Chris S del código, el Visual Studio 2008 muestras vienen con un ObjectDumper.

    Unidad:\Archivos De Programa\Microsoft Visual Studio 9.0\Samples\1033\LinqSamples\ObjectDumper

    • No es así en virtud de expresar las instalaciones 🙁
  9. 2

    Aquí es una alternativa:

    using System.Reflection;
    public void Print(object value)
    {
    PropertyInfo[] myPropertyInfo;
    string temp="Properties of "+value+" are:\n";
    myPropertyInfo = value.GetType().GetProperties();
    for (int i = 0; i < myPropertyInfo.Length; i++)
    {
    temp+=myPropertyInfo[i].ToString().PadRight(50)+" = "+myPropertyInfo[i].GetValue(value, null)+"\n";
    }
    MessageBox.Show(temp);
    }

    (sólo tocar el nivel 1, sin profundidad, pero se dice mucho)

    • Por favor, hacer que esto se parezca más a una respuesta alternativa, recibió su bandera y leer de nuevo. Me lo quitaron porque inicialmente parecía un seguimiento de los comentarios.
    • No sé realmente por qué un seguimiento de los comentarios es diferente o deben ser eliminados, pero voy a tratar de hacer que se vea como respuesta alternativa.
    • Las respuestas deben responder directamente a la pregunta, no acaba de traer más a la conversación. Comentarios (debajo de cada respuesta) estará disponible para usted una vez que alcanzó los 50 puntos de reputación. Esto hace, sin embargo, hablar directamente a la pregunta, Gracias de antemano por la edición de la misma para un poco de claridad
  10. 0

    Me encontré con un requisito similar en un Blazor proyecto, y se llegó a la siguiente muy simple componente a la salida de un objeto (y es hijo de los objetos) de datos en la pantalla:

    ObjectDumper.maquinilla de afeitar:

    @using Microsoft.AspNetCore.Components
    @using Newtonsoft.Json
    <div>
    <button onclick="@DumpVMToConsole">@ButtonText</button>
    <pre id="json">@_objectAsJson</pre>
    </div>
    @functions {
    //This component allows the easy visualisation of the values currently held in 
    //an object and its child objects.  Add this component to a page and pass in a 
    //param for the object to monitor, then press the button to see the object's data
    //as nicely formatted JSON
    //Use like this:  <ObjectDumper ObjectToDump="@_billOfLadingVM" />
    [Parameter]
    private object ObjectToDump { get; set; }
    [Parameter]
    private string ButtonText { get; set; } = "Show object's data";
    string _buttonText;
    string _objectAsJson = "";
    public void DumpVMToConsole()
    {
    _objectAsJson = GetObjectAsFormattedJson(ObjectToDump);
    Console.WriteLine(_objectAsJson);
    }
    public string GetObjectAsFormattedJson(object obj)
    {
    return JsonConvert.SerializeObject(
    value: obj, 
    formatting: Formatting.Indented, 
    settings: new JsonSerializerSettings
    {
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
    });
    }
    }

    Usted, a continuación, pega de que en algún lugar en un Blazor página de la siguiente manera:

    <ObjectDumper ObjectToDump="@YourObjectToVisualise" />

    Que luego muestra un botón, usted puede pulsar para ver el valor actual del objeto vinculado:

    objeto dumper clase

    Me he quedado que en un repo en GitHub: tomRedox/BlazorObjectDumper

Dejar respuesta

Please enter your comment!
Please enter your name here