一个涉及List <T>和对象转换的棘手问题

ind*_*dra 10 c# linq inheritance casting

我最近在一次面试时得到了这个问题,并且无法弄清楚如何优雅地做到这一点.从那时起,它一直在唠叨我,如果我对某些"现代"技术/技术缺乏了解,我就无法解决,或者我只是愚蠢.任何建议都会非常受欢迎.

问题

想象一个简单的类层次结构:

abstract class Person {
    public string Name { get; set; }
}

class Child : Person { }

class Parent : Person {
    public List<Person> Children { get; set; }
}

class Ancestor : Parent { }
Run Code Online (Sandbox Code Playgroud)

问题是如何遍历这些对象的层次结构并打印出遇到的所有人.因此对于以下场景:

Ancestor myAncestor = new Ancestor {    
    Name = "GrandDad",
    Children = new List<Person> { 
        new Child { Name = "Aunt" },
        new Child { Name = "Uncle" },
        new Parent {
            Name = "Dad", 
            Children = new List<Person> { 
                new Child { Name = "Me" }, 
                new Child { Name = "Sister" } 
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

输出应该是这样的:

GrandDad  
-    Aunt  
-    Uncle  
-    *Dad  
         -Me  
         -Sister

所有处理都需要在接受单个类型参数的单个方法中完成Ancestor.

我几乎没有想到,实现了一个简单的递归解决方案,但当然因为所涉及的对象相互关联的方式不是那么简单.

试着尽我所能,我想不出一个干净的方式这样做,我的采访后谷歌搜索建议我需要做一些事情(对我来说,只有一个工作知识LINQList<T>)比技术更先进的东西比排序web-dev编码我过去十年左右一直在做的事情.是这样的吗?或者我应该考虑退出软件开发,理由是我对它有垃圾吗?

更新

感谢大家的回复/建议.我接受了@Daniel Hilgarth的回答主要是因为它是我唯一能够真正理解的:-o

Dan*_*rth 9

我同意马克的评论说这种类型的系统是没有意义的.不过,你可以用代表来解决它.这有点作弊,因为基本上它们只不过是方法,但我们走了:

void PrintFamily(Ancestor a)
{
    Action<Parent, int> printParent = null;
    printParent = (parent, level) => 
    {
        var indentation = new string(' ', level * 4);
        var indentationChildren = new string(' ', (level + 1) * 4);
        Console.WriteLine(indentation + parent.Name);
        foreach(var child in parent.Children)
        {
            if(child is Child)
                Console.WriteLine(indentationChildren + child.Name);
            else if(child is Parent)
            {
                printParent((Parent)child, level + 1);
            }
        }
    };

    printParent(a, 0);
}
Run Code Online (Sandbox Code Playgroud)