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

本文关键字:连接 嵌套 LINQ 平面化 | 更新日期: 2023-09-27 18:18:47

我需要创建一个新的序列(最好使用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()方法(来自这篇文章),感觉我在正确的轨道上,但我似乎不能确切地弄清楚如何使查询工作。

那么,我如何使用LINQ创建这种类型的列表呢?

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

使用

from x in specializedContents
let t = x.GetType()
from i in t.GetInterfaces()
select new { Type = t.Name, Interface = i.Name };

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

与真正的扁平列表略有不同,但可能有用的是将所有内容塞进字典。

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