反思 - 递归内我自己的组件迭代对象的属性(Vb.Net/3.5)(Reflection - Ite

2019-08-05 04:10发布

我不知道是否有人能帮助我 - 我没有做什么与反思,但了解的基本原则。

我想要做的事:

我在开发收集了很多关于本地系统信息,网络等一类的过程是...用于自动错误报告。 而不必每次添加一个新的属性时间来改变我的测试工具,我想(理想),希望能够以连载的地段作为XML字符串,然后显示在一个文本框。

不幸的是,该框架将不会使用的只读属性的默认XML序列化(几乎所有的煤矿都是),因为它们将无法正常反序列化

MS说,这是一个功能“设计”,我想我能理解- -也许一个标记,以表明它本来也应该序列化将是有利的 [ 不知道我的假设是什么序列化必须去序列化的同意吗? ]

最初的办法是使性能gettable和可设置(与二传手抛出异常),但工作后整理这件事量似乎有点过度和我想的属性是只读的最终版本。

我需要什么帮助:

我目前的计划是利用反射递归通过我的最顶端聚会类的每个(公共)财产迭代。 问题是,我见过不递归处理事情的样本。 此外,我只是想,如果它在我的组件之一,检查对象的属性 - 否则,只需要调用的ToString就可以了。

如果我没有做的检查仅限于我的组装,我想我会得到(比如说)的字符串,然后由长度这反过来会的ToString方法...

对于这个项目的目的,我几乎可以保证我的代码中没有循环引用,并因为这只会被用来作为开发工具,所以我不是在意,现在横行,然后运行它。

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

提前谢谢了。

Answer 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


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


文章来源: Reflection - Iterate object's properties recursively within my own assemblies (Vb.Net/3.5)