我需要创建一个新序列(最好使用linq),列出一个类型及其实现的所有接口。
以下是一个例子:
public interface ITypeA { }
public interface ITypeB { }
public interface ITypeC { }
public class Class1 { }
public class Class2 : ITypeA, ITypeB, ITypeC { }
public class Class3 : ITypeC, ITypeA { }
var specializedContents = new object[] { new Class1(), new Class2(), new Class3() };
我正在尝试制作一个看起来像这样的序列。
------------------------------------------------------
| Type | Interface |
------------------------------------------------------
| Class2 | ITypeA |
| Class2 | ITypeB |
| Class2 | ITypeC |
| Class3 | ITypeC |
| Class3 | ITypeA |
------------------------------------------------------
我知道我需要在第一列使用[instance].GetType()
,在第二列使用[instance].GetType().GetInterfaces()
,但我无法解决如何扩展第一列并使其与第二个对齐。我看了很多,但我只能找到将序列包装到内部列表中的方法,但是找不到将预先存在的序列打包到外部列表中的方法。
我查看了.SelectMany()方法(来自this post),感觉就像我在正确的轨道上,但我似乎无法确切地知道如何使查询工作。
那么,如何使用LINQ创建这种类型的列表?
答案 0 :(得分:3)
使用此:
from x in specializedContents
let t = x.GetType()
from i in t.GetInterfaces()
select new { Type = t.Name, Interface = i.Name };
答案 1 :(得分:1)
SelectMany
确实是一种合理的方式。您可以将类型/接口对编码为Tuple
,或将@ david.s显示为匿名类型。
var specializedContents = new object[] { ... };
var typeInterfacePairs = specializedContents.Select(o => o.GetType())
.SelectMany(t => t.GetInterfaces().Select(i => Tuple.Create(t, i)));
// or
var typeInterfaceObjs = specializedContents.Select(o => o.GetType())
.SelectMany(t =>
t.GetInterfaces().Select(i => new { Type = t, Interface = i }));
答案 2 :(得分:0)
与真正的平面列表略有不同,但可能有用的是将所有内容都推到字典中。
var dict = specializedContents.Select(o => o.GetType())
.ToDictionary(k => k.Name, v => v.GetInterfaces());
使用如下所示的方式显示仍然很容易,但中间结构可能仍然有价值。
foreach(var kvp in dict)
{
foreach(var value in kvp.Value)
{
Console.WriteLine("| {0} | {1} |", kvp.Key, value);
}
}