0

Here is an example

class A
{
    public string Text = "";
    public IEnumerable<A> Children = new List<A>();
}
class B
{
    public string Text;
    public IEnumerable<B> Children = new List<B>();
}

static void Main(string[] args)
{
    // test
    var a = new A[]
    {
        new A() { Text = "1", Children = new A[]
        {
            new A() { Text = "11"},
            new A() {Text = "12"},
        }},
        new A() { Text = "2", Children = new A[]
        {
            new A() {Text = "21", Children = new A[]
            {
                new A() {Text = "211"},
                new A() {Text = "212"},
            }},
            new A() {Text = "22"},
        }},
    };

    B[] b = a ...;  // convert a to b type

}

My original problem is hierarchical data A in Model, which has to be displayed in the View, thus I have to create B type in ViewModel with INotifyPropertyChanged, etc. Converting from A to B for hierarchical data seems more complicated than a simple linq Cast<>.

If somebody is going to try to code, then here is the nice flattering function, can be used like this:

foreach (var item in b.Flatten(o => o.Children).OrderBy(o => o.Text))
    Console.WriteLine(item.Text);
Community
  • 1
  • 1
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Are you going to self-answer it and than update question to match answer? Not really sure what kind of help you are looking for. Assuming you already have code with recursion it would be nice to update question with what you have and why it does not work for you. – Alexei Levenkov Jul 20 '15 at 15:21
  • @AlexeiLevenkov, recursion you say? For some reasons I can't make it, my most recent idea was to flaten `a`, then `Cast<>`, then unflatten.. and I stuck at unflattening. Maybe I am overcomplicating it? If this sounds easy for you, can you please post an answer? – Sinatr Jul 20 '15 at 15:29
  • Sinatr, answer by StripligWarior (downvoted for some strange reason) works perfectly fine and probably shortest code you need to write. – Alexei Levenkov Jul 20 '15 at 15:35

1 Answers1

3

Use a recursive function that can translate an A into a B.

B BFromA(A a) {
    return new B { Text = a.Text, Children = a.Children.Select(BFromA).ToList() };
}

Usage:

B[] b = a.Select(BFromA).ToArray();  // convert a to b type
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • @Sinatr Code works perfectly fine. There is absolutely nothing special about passing method name ("method group") as delegate. – Alexei Levenkov Jul 20 '15 at 15:37
  • @Sinatr: `.Select()` is an extension method in the `System.Linq` namespace. You'll need to add `using System.Linq;` to the top of your C# file, as Alexei did in his sample. LINQ extension methods are so heavily used that we tend to take for granted that you will have included this namespace. – StriplingWarrior Jul 20 '15 at 19:03