嵌套类列出 LINQ

本文关键字:LINQ 嵌套 | 更新日期: 2023-09-27 17:56:33

我有以下类:

public class SerializedDelegate
{
    public List<GOEntry> goEntries = new List<GOEntry>();
}
public class GOEntry
{
    public string go;
    public List<MBEntry> mbEntries = new List<MBEntry>();
}
public class MBEntry
{
    public string mb;
    public List<MethodEntry> methodsEntries = new List<MethodEntry>();
}
public class MethodEntry
{
    public string method;
}

而这些数据:

var sd = new SerializedDelegate();
var eGo1 = new GOEntry { go = "Player1" };
var eGo2 = new GOEntry { go = "Player2" };
var eMb1 = new MBEntry { mb = "MB1" };
var eMb2 = new MBEntry { mb = "MB2" };
var eM1 = new MethodEntry { method = "target1" };
var eM2 = new MethodEntry { method = "target2" };
var eM3 = new MethodEntry { method = "target3" };
var eM4 = new MethodEntry { method = "target4" };
eMb1.methodsEntries.Add(eM1);
eMb1.methodsEntries.Add(eM2);
eMb2.methodsEntries.Add(eM3);
eMb2.methodsEntries.Add(eM4);
eGo1.mbEntries.AddRange(new[] { eMb1, eMb2 });
eGo2.mbEntries.Add(eMb1);
sd.goEntries.AddRange(new[] { eGo1, eGo2 });

我正在尝试做的 - 以以下形式打印它们:

     Player1: MB1.target1
     Player1: MB1.target2
     Player1: MB2.target3
     Player1: MB2.target4
     Player2: MB1.target1
     Player2: MB1.target2

我已经使用 foreach 循环打印了它们:

foreach (var goEntry in sd.goEntries) {
    foreach (var mbEntry in goEntry.mbEntries) {
        foreach (var methodEntry in mbEntry.methodsEntries)
            Console.WriteLine(goEntry.go + ": " + mbEntry.mb + "." + methodEntry.method);
    }
}

但是我想以 LINQ 的方式执行此操作 - 我想构造一个与我想要打印它们的方式相对应的 LINQ 结构 - 这样我只需要一个 foreach 循环(因此构造的枚举的长度是总方法的数量 - 在本例中为 6)。

我是这样开始的 - 但不知道如何进一步进行:

var entries = sd.goEntries
    .Select(g => new
    {
        GO = g.go,
        MBs = g.mbEntries,
        Methods = g.mbEntries.SelectMany(e => e.methodsEntries)
    });

最终,这些方法条目将在弹出窗口中 - 所以这就是为什么我需要一个结构,通过我可以很容易地分辨出哪个MBEntry属于哪个GOEntry,以及哪个MethodEntry属于哪个MBEntry

对不起,如果我不够清楚 - 如果是这种情况,请说出来。

谢谢。

嵌套类列出 LINQ

var entries = from goEntry in sd.goEntries
              from mbEntry in goEntry.mbEntries
              from methodEntry in mbEntry.methodsEntries
              select new { goEntry.go, mbEntry.mb, methodEntry.method };

您可以通过以下方式输出条目:

 foreach(var entry in entries)
    Console.WriteLine("{0}: {1}.{2}", entry.go, entry.mb, entry.method);

听起来你想要这样的东西:

var lines = from goEntry in sd.goEntries
            from mbEntry in goEntry.mbEnties
            from methodEntry in mbEntry.methodsEntries
            select string.Format("{0}: {1}.{2}",
                                 goEntry.go, mbEntry.mb, methodEntry.method);
foreach (var line in lines)
{
    Console.WriteLine(line);
}

或者,如果您希望稍后进行格式化:

var entries = from goEntry in sd.goEntries
              from mbEntry in goEntry.mbEnties
              from methodEntry in mbEntry.methodsEntries
              select new { goEntry, mbEntry, methodEntry };
foreach (var entry in entries)
{
    Console.WriteLine("{0}: {1}.{2}", entry.goEntry.go,
                      entry.mbEntry.mb, entry.methodEntry.method);
}

。或根据谢尔盖的答案捕获要格式化的单个值(goEntry.go等)。许多不同的方法:)

其他人给出了更好看的答案,但由于您在其他评论中询问了它的方法版本,我在这里介绍它:

sd.goEntries.SelectMany(
    ge=>ge.mbEntries.SelectMany(
        mb=>mb.methodsEntries.Select(
            me=>new {me.method, mb.mb, ge.go}
        )
    )
)
比查询

语法样式更难看出这是做什么,如其他两个当前答案所示。