【问题标题】:Reflection - Iterate object's properties recursively within my own assemblies (Vb.Net/3.5)反射 - 在我自己的程序集中递归迭代对象的属性 (Vb.Net/3.5)
【发布时间】:2010-11-27 12:05:24
【问题描述】:

我想知道是否有人可以帮助我 - 我在反思方面做得不多,但了解基本原则。

我想做的事:

我正在开发一个类,该类收集关于本地系统、网络等的大量信息,用于自动报告错误。不必在每次添加新属性时都更改测试工具,而是(理想情况下)希望能够将批次序列化为 XML 字符串并将其显示在文本框中。

不幸的是,框架不会对只读属性(几乎我的所有属性)使用默认的 XML 序列化程序,因为它们无法正确反序列化

[我不确定我是否同意任何序列化的东西都必须是可反序列化的假设——MS 说这是一个“设计”的功能,我想我可以理解——也许是一个标签表明它应该被序列化反正会有优势吗?]

最初的方法是使属性可获取和可设置(在设置器上抛出异常),但事后整理的工作量似乎有点过多,我希望这些属性在最终版本中是只读的.

我需要什么帮助:

我目前的计划是使用反射来递归地遍历我最顶层的聚集类的每个(公共)属性。问题是,我见过的样本不能递归处理。此外,我只想检查一个对象的属性(如果它在我的一个程序集中) - 否则只需调用 .ToString 即可。

如果我没有将检查限制在我的程序集中,我假设我会得到(比如说)一个字符串,该字符串包含一个 Length,而 Length 又将具有 .Tostring 方法...

为了这个项目的目的,我可以几乎保证我的代码中没有循环引用,因为这只会用作开发工具,所以我不是 担心它时不时地跑来跑去。

我会很感激一些例子/建议。

非常感谢。

【问题讨论】:

    标签: vb.net visual-studio-2008 reflection assemblies


    【解决方案1】:

    这有望帮助您入门。它将树直接打印到控制台,因此您需要调整以输出 XML。然后更改 IsMyOwnType 方法以过滤掉您感兴趣的程序集,现在它只关心与自身相同的程序集中的类型。

    Shared Sub RecurseProperties(o As Object, level As Integer)
        For Each pi As PropertyInfo In o.GetType().GetProperties()
            If pi.GetIndexParameters().Length > 0 Then Continue For
    
            Console.Write(New String(" "c, 2 * level))
            Console.Write(pi.Name)
            Console.Write(" = ")
    
            Dim propValue As Object = pi.GetValue(o, Nothing)
            If propValue Is Nothing Then
                Console.WriteLine("<null>")
            Else
                If IsMyOwnType(pi.PropertyType) Then
                    Console.WriteLine("<object>")
                    RecurseProperties(propValue, level+1)
                Else
                    Console.WriteLine(propValue.ToString())
                End If
            End If
    
        Next
    End Sub
    
    Shared Function IsMyOwnType(t As Type) As Boolean
        Return t.Assembly Is Assembly.GetExecutingAssembly()
    End Function
    

    【讨论】:

    • 我一直在研究类似的东西,最终得到了一些可行的东西,但却是意大利面条代码。您的示例更加简洁且有很大帮助 - 非常感谢
    • 当然,我的下一个问题是枚举列表...同样,我找到了一种方法,但它目前一团糟。如果/当我的代码处于可展示的状态时,我会发布最终版本。
    【解决方案2】:

    您在 c# 上的扩展版本可用于任何对象

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    
    namespace Extensions
    {
        public static class ObjectExtension
        {
            public static string ToStringProperties(this object o)
            {
                return o.ToStringProperties(0);
            }
        public static string ToStringProperties(this object o, int level)
        {
            StringBuilder sb = new StringBuilder();
            string spacer = new String(' ', 2 * level);
            if (level == 0) sb.Append(o.ToString());
            sb.Append(spacer);
            sb.Append("{\r\n");
            foreach (PropertyInfo pi in o.GetType().GetProperties())
            {
    
                if (pi.GetIndexParameters().Length == 0)
                {
                    sb.Append(spacer);
                    sb.Append("  ");
                    sb.Append(pi.Name);
                    sb.Append(" = ");
    
                    object propValue = pi.GetValue(o, null);
                    if (propValue == null)
                    {
                        sb.Append(" <null>");
                    } else {
                        if (IsMyOwnType(pi.PropertyType))
                        {
                            sb.Append("\r\n");
                            sb.Append(((object)propValue).ToStringProperties(level + 1));
                        } else{
                            sb.Append(propValue.ToString());
                        }
                    }
                    sb.Append("\r\n");
                }
            }
            sb.Append(spacer);
            sb.Append("}\r\n");
            return sb.ToString();
        }
        private static bool IsMyOwnType(Type t) 
    {
        return (t.Assembly == Assembly.GetExecutingAssembly());
    }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      • 2011-09-05
      • 1970-01-01
      • 2011-02-11
      • 2011-01-13
      • 2015-11-18
      • 1970-01-01
      相关资源
      最近更新 更多