2

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

static List<object> EnumerateObjectsInRange(object root);

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

有什么建议么?

编辑:

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

  1. 根对象的所有者将能够访问所有对象(公共可用对象)。
  2. 根对象所属的对象图引用的所有公共和私有对象。

第一个定义足以满足我的目的。

4

2 回答 2

3

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

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

于 2012-05-20T21:48:03.433 回答
0

以防万一有人觉得它有用,我正在分享我从usrHenk 的答案中编写的递归方法,它解决了我的问题:

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 是否为空),但它完成了工作。

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

于 2012-05-21T00:07:49.663 回答