c# - 如何迭代 C# 对象,查找特定类型的所有实例,以便构建这些实例的单独列表?

标签 c# reflection properties enumeration

我有一个需求有点类似于这个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 实例。

为了简化探索,我们可以假设如下:

  1. 仅探索属性。
  2. 没有无限引用循环。

目前,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/

相关文章:

c# - PropertyBuilder<T> 不包含 HasColumnType 的定义

java - 动态类加载时运行时注释扫描

java - 如何在对象的 JSON 属性中排除(在输出类内部)?

c# - 为什么在 ASP.NET Core Web API 中使用 SkiaSharp 会导致崩溃?

c# - 如何回溯函数调用?

c# - dotnet 核心 Entity Framework 连接已关闭

c# - 如何将类对象的 System.Reflection.PropertyInfo 名称提取为 csv 文件的第一行

api - 避免在包 API 中暴露反射

JavaScript object.hasOwnProperty(proName) vs lodash _.has(obj, proName) 函数

struct - 在 Rust 中拥有多个具有相同属性的结构的惯用方法是什么?