如何在给定根对象的情况下枚举所有可到达的对象?

时间:2012-05-20 21:00:34

标签: c# reflection reference

我想实现一个接收根对象的方法,并返回一个列表,其中包含对从根对象开始可以到达的所有对象的引用。它的签名是这样的:

static List<object> EnumerateObjectsInRange(object root);

我正在考虑使用GetProperties()检索PropertyInfo个对象的数组,然后使用GetValue()获取这些属性的值,最后再次为每个值调用GetProperties()并重复此过程,直到访问完整个对象图,但我不确定这是否是最好的方法。

有什么建议吗?

修改

我可以想到可达的两个定义:

  1. 根对象的所有者可以访问的所有对象(公共可用对象)。
  2. 根对象所属的对象图引用的所有公共和私有对象。
  3. 第一个定义足以满足我的目的。

2 个答案:

答案 0 :(得分:3)

你肯定需要字段,而不是属性。对象通过字段使其他对象保持活动,从不通过属性。您不需要特殊情况列表,因为它们包含您将使用GetFields找到的内部数组。但是,您需要特殊情况数组。

顺便说一下,我已经实现了这个算法,并发现它有效。

答案 1 :(得分:0)

万一有人发现它有用,我正在分享一个递归方法,我用 usr Henk的答案解决了我的问题:

static void EnumerateObjectsInRange(object root, HashSet<object> hashset)
{
    if (root == null || hashset.Contains(root))
    {
        return;
    }

    hashset.Add(root);
    FieldInfo[] fields = root.GetType().GetFields(BindingFlags.Static
                                                | BindingFlags.Instance
                                                | BindingFlags.Public
                                                | BindingFlags.NonPublic);

    foreach (FieldInfo field in fields)
    {
        object obj = field.GetValue(root);

        if (obj == null)
        {
            continue;
        }

        if (obj.GetType().IsSubclassOf(typeof(Array)))
        {
            foreach (object member in (Array)obj)
            {
                EnumerateObjectsInRange(member, hashset);
            }
        }

        EnumerateObjectsInRange(obj, hashset);
    }
}

这个方法仍然需要一些重构(并且不检查HashSet是否为null),但是它完成了工作。

要调用它,请提供根对象和存储访问对象的空HashSet。