【问题标题】:C#, get all collection properties from an objectC#,从一个对象中获取所有集合属性
【发布时间】:2011-03-02 17:59:11
【问题描述】:

我有一个包含 3 个 List 集合的类,如下所示。

我试图有一个逻辑来遍历对象的“集合” 属性并使用存储在这些集合中的数据进行一些操作。

我只是想知道是否有使用 foreach 的简单方法。 谢谢

public class SampleChartData
    {
        public List<Point> Series1 { get; set; }
        public List<Point> Series2 { get; set; }
        public List<Point> Series3 { get; set; }

        public SampleChartData()
        {
            Series1 = new List<Point>();
            Series2 = new List<Point>();
            Series3 = new List<Point>();
        }
    }

【问题讨论】:

  • 您是在寻找一种通用机制来查找任何对象中的所有集合,还是专门寻找一种在图表中显示所有系列的方法?在后一种情况下,我可以看到类似 IChartSeriesContainer 的内容,其中有一个返回 IEnumerable&lt;IEnumerable&lt;Point&gt;&gt;GetAllSeries 方法。
  • 嗨,我正在寻找一种通用机制来查找对象中特定类型的集合。但最后我决定采用一种更加灵活/动态的“List>”收集方法。

标签: c# reflection collections


【解决方案1】:

从对象中获取所有 IEnumerable 的函数:

public static IEnumerable<IEnumerable<T>> GetCollections<T>(object obj)
{
    if(obj == null) throw new ArgumentNullException("obj");
    var type = obj.GetType();
    var res = new List<IEnumerable<T>>();
    foreach(var prop in type.GetProperties())
    {
        // is IEnumerable<T>?
        if(typeof(IEnumerable<T>).IsAssignableFrom(prop.PropertyType))
        {
            var get = prop.GetGetMethod();
            if(!get.IsStatic && get.GetParameters().Length == 0) // skip indexed & static
            {
                var collection = (IEnumerable<T>)get.Invoke(obj, null);
                if(collection != null) res.Add(collection);
            }
        }
    }
    return res;
}

然后你可以使用类似的东西

var data = new SampleChartData();
foreach(var collection in GetCollections<Point>(data))
{
    foreach(var point in collection)
    {
        // do work
    }
}

遍历所有元素。

【讨论】:

    【解决方案2】:

    使用反射来获取对象的属性。然后遍历这些以查看is IEnumerable&lt;T&gt;。然后遍历 IEnumerable 属性

    【讨论】:

    • 需要注意的是,字符串也显示为 IEnumerable
    【解决方案3】:

    您可以使用反射从对象中获取属性列表。此示例获取所有属性并将其名称和计数打印到控制台:

    public static void PrintSeriesList()
    {
        SampleChartData myList = new SampleChartData();
    
        PropertyInfo[] Fields = myList.GetType().GetProperties();
    
        foreach(PropertyInfo field in Fields)
        {
            var currentField =  field.GetValue(myList, null);
            if (currentField.GetType() == typeof(List<Point>))
            {
                Console.WriteLine("List {0} count {1}", field.Name, ((List<Point>)currentField).Count);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      刚刚找到了一个快速的解决方案,但也许你们中的一些人有更好的方法。 这就是我所做的。

      SampleChartData myData = DataFeed.GetData();
      Type sourceType = typeof(SampleChartData);
      foreach (PropertyInfo pi in (sourceType.GetProperties()))
      {
          if (pi.GetValue(myData, null).GetType() == typeof(List<Point>))
          {
              List<Point> currentSeriesData = (List<Point>)pi.GetValue(myData, null);
      
              // then do something with the data
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-22
        • 2017-01-07
        • 1970-01-01
        • 2014-05-13
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多