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); } } |
这个方法仍然需要一些重构(它不检查哈希集是否为空),但它可以完成任务。
要调用它,请提供根对象和一个空的哈希集,其中存储访问过的对象。