C#,从一个对象中获取所有集合属性

5

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

我正在尝试编写一种逻辑,通过迭代对象的“collection”属性并使用存储在这些集合中的数据执行某些操作。

我只是想知道是否有一种使用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 的接口,并提供一个 GetAllSeries 方法,返回 IEnumerable<IEnumerable<Point>> - Dan Bryant
嗨,我一直在寻找一种通用机制来查找对象中特定类型的集合。但最终我决定采用一种“List<<List<Point>>”集合方法,这种方法更加灵活/动态。 - Eatdoku
4个回答

13

获取对象中所有 IEnumerable<T> 的函数:

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

使用反射获取对象的属性。然后迭代这些属性,查看是否为 IEnumerable<T>类型。然后迭代IEnumerable属性。


5
有一点需要注意,字符串也可以作为IEnumerable出现。 - Chris Pitman

0

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

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);
        }
    }
}

0

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

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接