如何使用反射递归打印对象属性的值

ali*_*ray 14 c# reflection

为了帮助调试我正在处理的一些代码,我开始编写一个方法来递归地打印出对象属性的名称和值.但是,大多数对象都包含嵌套类型,我也想打印它们的名称和值,但仅限于我定义的类型.

这是我到目前为止的概述:

public void PrintProperties(object obj)
{
    if (obj == null)
        return;

    Propertyinfo[] properties = obj.GetType().GetProperties();

    foreach (PropertyInfo property in properties)
    {
        if ([property is a type I have defined])
        {
            PrintProperties([instance of property's type]);
        }
        else
        {
            Console.WriteLine("{0}: {1}", property.Name, property.GetValue(obj, null));
        }
    }
Run Code Online (Sandbox Code Playgroud)

支架之间的部件是我不确定的地方.

任何帮助将不胜感激.

car*_*ira 26

下面的代码尝试了这一点.对于"类型I已定义",我选择查看同一程序集中的类型与正在打印其属性的类型,但如果您的类型在多个程序集中定义,则需要更新逻辑.

public void PrintProperties(object obj)
{
    PrintProperties(obj, 0);
}
public void PrintProperties(object obj, int indent)
{
    if (obj == null) return;
    string indentString = new string(' ', indent);
    Type objType = obj.GetType();
    PropertyInfo[] properties = objType.GetProperties();
    foreach (PropertyInfo property in properties)
    {
        object propValue = property.GetValue(obj, null);
        if (property.PropertyType.Assembly == objType.Assembly && !property.PropertyType.IsEnum)
        {
            Console.WriteLine("{0}{1}:", indentString, property.Name);
            PrintProperties(propValue, indent + 2);
        }
        else
        {
            Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 此代码不检测_cycles_.如果存在一个循环,它将最终抛出一个`StackOverflowException`. (4认同)

Leo*_*lev 8

您想要使用反射有什么特别的原因吗?相反,您可以像这样使用JavaScriptSerializer:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = serializer.Serialize(obj);
Console.WriteLine(json);
Run Code Online (Sandbox Code Playgroud)

它将递归地包含string中的所有属性,并在出现循环引用的情况下抛出异常.