如何在C#中定义一个可继承的树类来构建由不同类类型组成的树状数据结构?

我一直在阅读这个主题一段时间,但我只是不太了解 C# 语法。希望这对您来说很清楚,并且您愿意帮助我。我发现的例子是相同类型或类的树结构,这不是我在这里需要的。


简而言之,我希望能够定义任意类,例如下面的 NodeClassA、NodeClassB、NodeClassC,并且能够将任意数量的这些相互附加以形成如下所示的任意树数据结构。


每个节点都应该能够访问其父节点。


任何人都可以帮助正确定义下面的 MyTreeClass 吗?


NodeClassB

__NodeClassC

__NodeClassA

____NodeClassB

____NodeClassB

____NodeClassA

__NodeClassA

____NodeClassC

__NodeClassB

__NodeClassC


class MyTreeClass

{

    public void AddChild(T NodeClassX) { }

    public T GetChild() { }

}

class NodeClassA:MyTreeClass

{

    public void foo(int a) { }

}


class NodeClassB : MyTreeClass

{

    public void foo(int b) { }

}


class NodeClassC : MyTreeClass

{

    public void foo(int c) { }

}


青春有我
浏览 193回答 3
3回答

RISEBY

这在严格的类型安全方式中是不可能的,因为类型安全是在编译时确保的,这需要静态声明类型。但是树是在运行时动态构建的,具有不同的节点类型。要走的路是拥有一个可以是通用的静态节点数据类型。可以从给定的基本数据类型导出不同类型的数据。使用多态来处理它们。即使用具有不同实现的相同方法集。public class TreeNode<T>{&nbsp; &nbsp; public T Data { get; set; }&nbsp; &nbsp; private List<TreeNode<T>> _children = new List<TreeNode<T>>();&nbsp; &nbsp; public IEnumerable<TreeNode<T>> Children => _children;&nbsp; &nbsp; public TreeNode<T> AddChild(T data)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var node = new TreeNode<T> { Data = data };&nbsp; &nbsp; &nbsp; &nbsp; _children.Add(node);&nbsp; &nbsp; &nbsp; &nbsp; return node;&nbsp; &nbsp; }&nbsp; &nbsp; public void VisitPreOrder(Action<T, int> action, int level)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; action(Data, level);&nbsp; &nbsp; &nbsp; &nbsp; foreach (TreeNode<T> node in Children) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.VisitPreOrder(action, level + 1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}public class Tree<T>{&nbsp; &nbsp; public TreeNode<T> Root { get; } = new TreeNode<T>();&nbsp; &nbsp; public void VisitPreOrder(Action<T, int> action)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Root.VisitPreOrder(action, 0);&nbsp; &nbsp; }}现在您可以拥有与树完全无关的数据类:public class A{&nbsp; &nbsp; public int Index { get; set; }&nbsp; &nbsp; public virtual void PrintLine()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine($"A {Index}");&nbsp; &nbsp; }}public class B : A{&nbsp; &nbsp; public override void PrintLine()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine($"B {Index}");&nbsp; &nbsp; }}public class C : B{&nbsp; &nbsp; public override void PrintLine()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine($"C {Index}");&nbsp; &nbsp; }}从您的示例创建树结构TreeNode<A> node;var tree = new Tree<A>();tree.Root.Data = new B { Index = 0 };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // NodeClassBtree.Root.AddChild(new C { Index = 1 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// __NodeClassCnode = tree.Root.AddChild(new A { Index = 2 });&nbsp; // __NodeClassAnode.AddChild(new B { Index = 3 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ____NodeClassBnode.AddChild(new B { Index = 4 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ____NodeClassBnode.AddChild(new A { Index = 5 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ____NodeClassAnode = tree.Root.AddChild(new A { Index = 6 });&nbsp; // __NodeClassAnode.AddChild(new C { Index = 7 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ____NodeClassCtree.Root.AddChild(new B { Index = 8 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// __NodeClassBtree.Root.AddChild(new C { Index = 9 });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// __NodeClassC&nbsp;因为每个数据类型(基类型或派生类型)都做适合其类型的事情,所以您不需要知道它的确切类型。这称为多态。这将打印树结构:tree.VisitPreOrder((item, level) => {&nbsp; &nbsp; Console.Write(new string('_', 4 * level));&nbsp; &nbsp; item.PrintLine();});B 0____C 1____A 2 ____B3 ____B4________A 5____A 6________C 7____B 8____C 9请注意,T在声明Tree<T>andTreeNode<T>类时,您不需要知道具体的数据类型,因为它T是通用的。你也可以声明var stringTree = new Tree<string>();var intTree = new Tree<int>();

红颜莎娜

您可能正在寻找复合模式,这是一种对树结构建模的常用方法,例如一个文件系统,其中您有一个叶子(文件)和容器(文件夹),而容器可以包含其他容器或叶子本身。在您的情况下,至少到目前为止您描述的方式要简单一些,因为这些节点之间没有行为差异。所以对于你的结构,节点实际上可以是浅的,你只需要在你的基类中实现组合。这样,您就没有叶子,而只有(不同的)容器。public abstract class BaseNode{&nbsp; &nbsp; public IList<BaseNode> Children&nbsp; &nbsp; { get; } = new List<BaseNode>();}public class NodeClassA : BaseNode { }public class NodeClassB : BaseNode { }public class NodeClassC : BaseNode { }然后你就可以构建你的结构了。

慕娘9325324

只需让您的任意类继承或组合某种类型的集合即可。例如,您的任意类都可以是列表。增强将是 add 方法设置子级的父级并且父级是一个属性。
打开App,查看更多内容
随时随地看视频慕课网APP