LINQ - 展平嵌套序列,使其与父序列连接

时间:2014-08-19 18:00:21

标签: c# linq

我需要创建一个新序列(最好使用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创建这种类型的列表?

3 个答案:

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