C# 对象转储器类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1347375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:27:38  来源:igfitidea点击:

object dumper class

c#object-dumper

提问by Chris S

I'm looking for a class that can output an object and all its leaf values in a format similar to this:

我正在寻找一个可以以类似于以下格式输出对象及其所有叶值的类:

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

(Or a clearer format). This would be equivalent to:

(或更清晰的格式)。这相当于:

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

A kind of string representation of the PropertyGrid control, minus having to implement a large set of designers for each type.

一种 PropertyGrid 控件的字符串表示形式,无需为每种类型实现大量设计器。

PHP has something that does this called var_dump. I don't want to use a watch, as this is for printing out.

PHP 有一个叫做var_dump 的东西。我不想用手表,因为这是用来打印的。

Could anyone point me to something like this if it exists? Or, write one for a bounty.

如果存在这样的事情,有人可以指出我吗?或者,写一个赏金。

采纳答案by Chris S

The object dumper posted in sgmoore's link:

在 sgmoore 的链接中发布的对象转储程序:

//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 Update

2015年更新

YAML also serves this purpose quite well, this is how it can be done with YamlDotNet

YAML 也很好地达到了这个目的,这就是 YamlDotNet 的实现方式

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

回答by Jake Pearson

You could write that very easily with a little bit of reflection. Something kind of like:

你可以很容易地写出一点点反思。有点像:

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

You can write up the PrintArray and PrintProperty methods.

您可以编写 PrintArray 和 PrintProperty 方法。

回答by AJ.

If you don't feel like copying and pasting Chris S's code, the Visual Studio 2008 samples come with an ObjectDumper.

如果您不想复制和粘贴 Chris S 的代码,Visual Studio 2008 示例附带一个 ObjectDumper。

Drive:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\LinqSamples\ObjectDumper

驱动器:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\LinqSamples\ObjectDumper

回答by Vdex

You could use the JSON serialiser, which should be easy to read for anyone use to working with JSON

您可以使用 JSON 序列化程序,对于习惯使用 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()); 

回答by Ohad Schneider

For most classes, you could use the DataContractSerializer

对于大多数类,您可以使用DataContractSerializer

回答by mythz

I have a handy T.Dump() Extension methodthat should be pretty close to the results you're looking for. As its an extension method, its non-invasive and should work on all POCO objects.

我有一个方便的 T.Dump() 扩展方法,它应该非常接近您正在寻找的结果。作为一种扩展方法,它是非侵入性的,应该适用于所有 POCO 对象。

Example Usage

示例用法

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

Example 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
    }
}

回答by Dan Diplo

Updated 2019

2019 年更新

You can find the ObjectDumper projecton GitHub. You can also add itvia Visual Studio via NuGet package manager.

您可以在 GitHub 上找到ObjectDumper 项目。您还可以通过 NuGet 包管理器通过 Visual Studio添加它

回答by e-motiv

Here is an alternative:

这是一个替代方案:

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

(just touching level 1, no depth, but says a lot)

(只是触及1级,没有深度,但说了很多)

回答by Dan Lugg

If you're working with markup, System.Web.ObjectInfo.Print(ASP.NET Web Pages 2) will accomplish this, nicely formatted for HTML.

如果您正在使用标记,System.Web.ObjectInfo.Print( ASP.NET Web Pages 2) 将完成此操作,并为 HTML 很好地格式化。

For example:

例如:

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

In a webpage, produces:

在网页中,产生:

ObjectInfo.Print(...)

ObjectInfo.Print(...)

回答by Nathan Pond

I know this is an old question, but thought I'd throw out an alternative that worked for me, took me about two minutes to do.

我知道这是一个老问题,但我想我会抛出一个对我有用的替代方法,花了我大约两分钟的时间。

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

安装Newtonsoft Json.NET: http://james.newtonking.com/json

(or nuget version) http://www.nuget.org/packages/newtonsoft.json/

(或 nuget 版本)http://www.nuget.org/packages/newtonsoft.json/

Reference Assembly:

参考装配:

using Newtonsoft.Json;

Dump JSON string to log:

转储 JSON 字符串以记录:

txtResult.Text = JsonConvert.SerializeObject(testObj);