关于c#:如何枚举给定根对象的所有可到达对象?

How to enumerate all reachable objects given a root object?

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

1
static List<object> EnumerateObjectsInRange(object root);

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

有什么建议吗?

编辑:

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

  • 根对象的所有者可以访问的所有对象(公共可用对象)。
  • 根对象所属的对象图引用的所有公共和私有对象。
  • 第一个定义对我来说已经足够了。


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

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


    为了防止有人发现它有用,我分享了一个我从USR和Henk的答案中编写的递归方法,解决了我的问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    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);
        }
    }

    这个方法仍然需要一些重构(它不检查哈希集是否为空),但它可以完成任务。

    要调用它,请提供根对象和一个空的哈希集,其中存储访问过的对象。