首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用GetProperties遍历对象

使用GetProperties遍历对象
EN

Stack Overflow用户
提问于 2017-02-23 14:58:42
回答 1查看 52关注 0票数 1

我希望看到一个对象的所有属性,我希望看到一个对象打印出来。类似perls的Data::Dumper或php的var_dump

我已经尝试了我自己的代码,但最终还是尝试了我在网上找到的这个。但是,每个代码在StackOverFlowException上都会失败,这是由于对象对自身的引用造成的。

在下面的例子中,我试图打印出对象CurrentThread,但这是一个Thread型的类,它有一个名为CurrentThread的属性,它指向同一个对象,我陷入了一个无限的循环中。

.Net中有没有我不知道的方法,或者我应该如何解决这个问题。我在想,也许一个对象/类可以有一个子对象,而这个子对象又有一个父属性,这也会导致无限循环。

由于在其他语言中有转储对象的方法,这当然不是第一次检测到此问题。

如何解决这个问题呢?

我希望打印出所有数据,而不仅仅是(作为示例):

代码语言:javascript
复制
obj.arr = string[]

我需要:

代码语言:javascript
复制
obj.arr = ["a", "b"]

有人对我有什么好的建议吗?

编辑:我已经将示例重写为:(来自以下原始问题的旧代码)。

调用代码:

代码语言:javascript
复制
        var cache = new HashSet<object>();
        var sb = new StringBuilder();
        ParseObject(System.Threading.Thread.CurrentThread, 0, sb, cache);

方法:

代码语言:javascript
复制
private void ParseObject(object o, int level, StringBuilder sb, HashSet<object> cache) {
        if (o == null) {
            sb.Append("NULL");
            return;
        }

        var type = o.GetType();

        switch (type.FullName)
        {
            case "System.String":
                sb.Append(o).AppendLine();
                return;
            case "System.Int16":
            case "System.Int32":
            case "System.Int64":
                sb.Append(o).AppendLine();
                return;
            case "System.Single":
                sb.Append(o).AppendLine();
                return;
            case "System.Decimal":
                sb.Append(o).AppendLine();
                return;
            case "System.Double":
                sb.Append(o).AppendLine();
                return;
            case "System.DateTime":
                sb.Append(((DateTime)o).ToString("yyyy-MM-dd HH:mm:ss")).AppendLine();
                return;
        }

        if (cache.Contains(o))
        {
            sb.Append("REFERENCE TO OLD OBJECT");
            return;
        }
        cache.Add(o);

        if (o is IEnumerable<object>) {
            IEnumerable<object> io = o as IEnumerable<object>;
            int i = 0;
            foreach (object o1 in io) {
                sb.Append("[" + i + "] = ");
                ParseObject(o1, level+1, sb, cache);
            }
            return;
        }

        var hasProperties = false;
        foreach (PropertyInfo prop in type.GetProperties()) {
            hasProperties = true;
            sb.Append(new string('\t', level));
            sb.Append(prop.Name).Append("=");
            object element = prop.GetValue(o);
            ParseObject(element, level + 1, sb, cache);
        }

        if (!hasProperties) {
            sb.Append(o).AppendLine();
        }
    }

老例子:

代码语言:javascript
复制
   var sb = new StringBuilder();
   PrintProperties(System.Threading.Thread.CurrentThread, 0, sb);

    public void PrintProperties(object obj, int indent, StringBuilder sb)
    {
        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);
            var elems = propValue as IList;
            if (elems != null)
            {
                foreach (var item in elems)
                {
                    PrintProperties(item, indent + 3, sb);
                }
            }
            else
            {
                // This will not cut-off System.Collections because of the first check
                if (property.PropertyType.Assembly == objType.Assembly)
                {
                    //Console.WriteLine("{0}{1}:", indentString, property.Name);
                    sb.AppendLine(string.Format("{0}{1}:", indentString, property.Name));

                    PrintProperties(propValue, indent + 2, sb);
                }
                else
                {
                    //Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
                    sb.AppendLine(string.Format("{0}{1}: {2}", indentString, property.Name, propValue));
                }
            }
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2017-02-23 15:12:54

您可以使用Json.Net进行简单而快速的序列化

代码语言:javascript
复制
Console.WriteLine(JsonConvert.SerializeObject(
    System.Threading.Thread.CurrentThread,
    Formatting.Indented,
    new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Serialize
    }));

这将产生

代码语言:javascript
复制
{
  "ManagedThreadId": 9,
  "ExecutionContext": {},
  "Priority": 2,
  "IsAlive": true,
  "IsThreadPoolThread": false,
  "IsBackground": false,
  "ThreadState": 0,
  "ApartmentState": 1,
  "CurrentUICulture": "en-US",
  "CurrentCulture": "en-US",
  "Name": null
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42409006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档