Nested classes lists LINQ

I have the following classes:

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

And this data:

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

What I'm trying to do - is print them in the following form:

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

I have printed them using foreach loops:

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

But I want to do it in a LINQ way - I want to construct a LINQ structure that corresponds to how I want to print them - so that I only need one foreach loop (so the length of the constructed enumerable is the number of total methods - in this case, 6).

I started like this - but no idea how to proceed further:

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

Eventually, those method entries will be in a popup - so that's why I need a structure, that through out I could easily tell which MBEntry belongs to which GOEntry, and what MethodEntry belongs to which MBEntry.

Sorry if I wasn't clear enough - if that's the case, please say so.

Thanks.

Jon Skeet
people
quotationmark

It sounds like you want something like:

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

Or if you'd rather do the formatting later:

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

... or capture the individual values to format (goEntry.go etc) as per Sergey's answer. Lots of different approaches :)

people

See more on this question at Stackoverflow