按接口实现对项目集合进行分组

时间:2016-12-12 18:22:33

标签: c# linq generics collections

我有一个对象集合,它们都有一个共同的基类型。这些对象在许多不同的级别派生,所有属性都来自接口实现。

// my list of all the items i have (Item being the base class)
var items = new List<Item>();

现在我需要按照它们实现的接口对这些项进行分组,但每个类都实现多个接口。

为了得到我的所有接口,我使用了Assembly反射:

Assembly.GetExecutingAssembly().GetTypes().Where(o => o.IsInterface).ToList();

这很可爱,但问题是我得到了Type对象的列表,所以我不能轻易地迭代并使用Linq查询每种类型的项目并检索分组的集合。我知道我必须手动构建集合我希望使用OfType<>但我不能使用Type

这里是我希望它在决赛中的样子:

// my list of all the items i have (Item being the base class)
var items = new List<Item>();

// get all interface of my assembly
var interfaces = Assembly.GetExecutingAssembly().GetTypes().Where(o => o.IsInterface).ToList();

// create an anonymous group with type and list of items of that type
var groups = interfaces.Select(interfaceType=> 
    new 
        { 
            Type = interfaceType, 
            Items = items.OfType<interfaceType>().ToList() // here's my issue
        });

我想知道是否有一些我忽略了什么并且没有看到或者我确实需要逐项比较项目以确定它们是否实现了类型。或者我的第二个解决方案是使用items.Where(item => items as [My Type]).Where(item=> item != null)而不是更清洁。

编辑: 这是一个可能有帮助的数据样本

inputs (3 classes) : 

item 1 : ISquare, IRectangle, IData
item 2 : IRectangle, IData, IReporting
item 3 : IData

Desired output (collection of 4 because 4 interface exists) :

{ ISquare, { item 1 }},
{ IRectangle, { item 1, item 2 }},
{ IData, { item 1, item 2, item 3 }},
{ IReporting, { item 2, item 3 }}

1 个答案:

答案 0 :(得分:1)

由于interfaceTypeSystem.Type类型的对象,因此该变量不能用作OfType<T>()方法的类型参数。

您可以将IsAssignableFromWhere一起使用,如下所示:

var groups = interfaces.Select(interfaceType => new { 
    Type = interfaceType
,   Items = items.Where(item => interfaceType.IsAssignableFrom(item.GetType()).ToList()
});