我有一个需求有点类似于这个question , 除了它需要对源对象进行更深入的探索。
这是一个代码示例:
public class Target {};
public class Analyzed
{
public Target EasyOne { get; set; }
public IList<Target> ABitMoreTricky { get; set; }
public IList<Tuple<string, Target>> Nightmare { get; set; }
}
从 Analyzed
实例中,我想提取所有 Target
实例。
为了简化探索,我们可以假设如下:
- 仅探索属性。
- 没有无限引用循环。
目前,EasyOne
是......简单,但我正在寻找一些策略来让所有 Target
实例丢失在更棘手的结构中。
最佳答案
按照这些思路怎么样:
public List<T> FindAllInstances<T>(object value) where T : class
{
HashSet<object> exploredObjects = new HashSet<object>();
List<T> found = new List<T>();
FindAllInstances(value, exploredObjects, found);
return found;
}
private void FindAllInstances<T>(object value, HashSet<object> exploredObjects, List<T> found) where T : class
{
if (value == null)
return;
if (exploredObjects.Contains(value))
return;
exploredObjects.Add(value);
IEnumerable enumerable = value as IEnumerable;
if (enumerable != null)
{
foreach(object item in enumerable)
{
FindAllInstances<T>(item, exploredObjects, found);
}
}
else
{
T possibleMatch = value as T;
if (possibleMatch != null)
{
found.Add(possibleMatch);
}
Type type = value.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty);
foreach(PropertyInfo property in properties)
{
object propertyValue = property.GetValue(value, null);
FindAllInstances<T>(propertyValue, exploredObjects, found);
}
}
private void TestIt()
{
Analyzed analyzed = new Analyzed()
{
EasyOne = new Target(),
ABitMoreTricky = new List<Target>() { new Target() },
Nightmare = new List<Tuple<string, Target>>() { new Tuple<string, Target>("", new Target()) }
};
List<Target> found = FindAllInstances<Target>(analyzed);
MessageBox.Show(found.Count.ToString());
}
关于c# - 如何迭代 C# 对象,查找特定类型的所有实例,以便构建这些实例的单独列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9518554/