oggetto dumper classe

Sto cercando una classe in grado di emettere un oggetto e tutti i suoi valori foglia, in un formato simile a questo:

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

(O una più chiara lettura del formato). Questo sarebbe 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 sorta di rappresentazione di stringa di controllo PropertyGrid, meno la necessità di implementare un gran numero di progettisti per ogni tipo.

PHP è qualcosa che fa questo chiamato var_dump. Non voglio utilizzare un orologio, questo è per la stampa.

Qualcuno potrebbe indicarmi a qualcosa di simile a questo, se esiste? Oppure, scrivere uno per una taglia.

OriginaleL’autore Chris S | 2009-08-28

11 Replies
  1. 49

    Oggetto dumper pubblicato in 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 Aggiornamento

    YAML serve anche a questo scopo abbastanza bene, questo è come si può fare 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);
        }
    Sarebbe fantastico se ci fosse un modo per deserializzare questo in un oggetto. 🙂
    ObjectDumper non visualizza il contenuto di un array.
    In DumpAsYaml() direi piuttosto cambiare Console.WriteLine() per Debug.WriteLine() così che funziona non solo su WebForms/Console (e, probabilmente, WTF, non sono sicuro) ma WebForms. Ovviamente sto dando per scontato che è la modalità di debug (ma chi sarà chiamata anche DumpAsYaml() in realse modalità)?
    Upvote per YAML, sembra che il formato OP vuole è praticamente YAML. Serializzatore è tutto ciò che lui vuole.
    //Copyright (C) Microsoft Corporation. Tutti i diritti riservati.

    OriginaleL’autore Chris S

  2. 29

    Si potrebbe utilizzare JSON serialiser, che dovrebbe essere di facile lettura per chiunque utilizzare per lavorare 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()); 
    Ho il codice che consentirà l’output JSON più facile da leggere (line feed) qui stackoverflow.com/questions/5881204/…
    Questa è la migliore risposta. Perché non usare Serializzazione per eseguire il dump di un oggetto? Si può semplicemente utilizzare un JSON visualizzatore per i rientri, elenchi, etc.
    Anche una buona alternativa dovrebbe essere quello di utilizzare Newtonsoft Json biblioteca, che molti di noi già conoscono e che è veramente facile da usare. JsonConvert.SerializeObject(items, Formatting.Indented) per l’output formattato. Su nuget: nuget.org/packages/Newtonsoft.Json
    Per utilizzare un serializzatore JSON è un ottimo suggerimento, e l’utilizzo di NewtonSoft JSON per fare ancora meglio. Grazie mille!
    Io uso il tuo codice, ma non funziona, quindi cambiare per essere come questo: NameValueCollection nvc = Context.Request.Form; JavaScriptSerializer serializer = new JavaScriptSerializer (); string json = serializer.Serialize (nvc); Context.Response.Write (json);

    OriginaleL’autore Vdex

  3. 13

    Se si sta lavorando con il margine di profitto, Sistema.Web.ObjectInfo.Stampa (ASP.NET Pagine Web 2) consentirà di raggiungere questo obiettivo, ben formattato in HTML.

    Per esempio:

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

    In una pagina web, produce:

    oggetto dumper classe

    molto bello, non sapevo di
    Qualsiasi idea di come questo può essere utilizzato con Webforms?

    OriginaleL’autore Dan Lugg

  4. 12

    Ecco una estensione di visual studio che ho scritto a fare questo:

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

    in azione:
    oggetto dumper classe

    Sarebbe bello se il C# per la generazione di oggetti roba sarebbe una dll separata/nuget-pacchetto in modo che si potrebbe usare in LinqPad per on-the-fly oggetto di codice di discariche. Dopo quasi un decennio .net dev mi manca ancora il perl Data::Dumper.
    Questa è una grande estensione, Grazie.
    Questo sembra destinato a essere usato durante il debug interattivo — giusto? Oppure possono essere utilizzati in altri modi?
    questo è corretto, è necessario essere interrotto in un punto di interruzione per esportare l’oggetto. Simile a come utilizzare i locali o guardare la finestra.
    Possiamo chiamare questo da codice?

    OriginaleL’autore Omar Elabd

  5. 7

    Si potrebbe scrivere che molto facilmente con un po ‘ di riflessione. Qualcosa tipo:

    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);
            }         
        }
    }

    È possibile scrivere il PrintArray e PrintProperty metodi.

    Sto cercando uno che già esiste
    La più vicina che ho visto è ObjectDumper. Vedere questa domanda stackoverflow.com/questions/360277/…
    Ho scritto quello che la maggior parte Jakers, però, aveva pensato che questo deve esistere. Darò jakers 1 per l’impegno (non compilare ma non è un problema). Sembra sgmoore link rende questo richiudibili
    Ho un No overload for method 'GetValue' takes 1 arguments con questo..

    OriginaleL’autore Jake Pearson

  6. 7

    Ho un pratico T. Dump() metodo di Estensione che dovrebbe essere abbastanza vicino per i risultati che stai cercando. Come un metodo di estensione, la sua non-invasiva e dovrebbe funzionare su tutti i oggetti POCO.

    Esempio Di Utilizzo

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

    Esempio Di Output

    {
        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, eccellente. Avrei voluto che questo era stampato il nome di una proprietà di troppo

    OriginaleL’autore mythz

  7. 6

    So che questa è una vecchia questione, ma ho pensato di buttare fuori un’alternativa che ha funzionato per me, mi ci sono voluti circa due minuti per fare.

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

    (o nuget versione) http://www.nuget.org/packages/newtonsoft.json/

    Di Riferimento Montaggio:

    using Newtonsoft.Json;

    Dump di una stringa JSON per la registrazione:

    txtResult.Text = JsonConvert.SerializeObject(testObj);
    L’unica cosa brutta di questa soluzione è enumerazioni mostra in formato numerico invece del loro valore di testo. Una bella soluzione anche se altrimenti.
    Ecco una fodera di bella formattazione e l’enumerazione di nomi: Newtonsoft.Json.JsonConvert.SerializeObject(testObj, Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonSerializerSettings() { Converters = new List<Newtonsoft.Json.JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter() } })
    E se si desidera serializzare i campi privati, è possibile annotare la classe corrispondente(es) con: [JsonObject(MemberSerialization.Fields)]

    OriginaleL’autore Nathan Pond

  8. 2

    Se non hai voglia di copiare e incollare Chris S codice di Visual Studio 2008 campioni di venire con un ObjectDumper.

    Unità:\Programmi\Microsoft Visual Studio 9.0\Samples\1033\LinqSamples\ObjectDumper

    Non così in condizioni di esprimere le installazioni 🙁

    OriginaleL’autore AJ.

  9. 2

    Qui è un’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);
    }

    (solo toccando il livello 1, senza profondità, ma la dice lunga)

    Si prega di fare sembrare più come una risposta alternativa, ricevuto la tua bandiera e leggerlo di nuovo. L’ho tolto perché, inizialmente, sembrava un follow-up di commento.
    Non so davvero perché un follow-up di commento è diverso o dovrebbe essere eliminato, ma cercherò di farlo sembrare come risposta alternativa.
    Le risposte dovrebbero rispondere direttamente alla domanda, non solo portare più la conversazione. Commenti (sotto ogni risposta) sarà disponibile una volta raggiunti i 50 punti di reputazione. Questo, tuttavia, di parlare direttamente alla domanda, Grazie in anticipo per la modifica di esso per un po ‘ di chiarezza

    OriginaleL’autore e-motiv

Lascia un commento