在C#中,我有一个看起来像这样的侵入式树结构:
public abstract class Node { Container parent; Node nextNode; Node prevIoUsNode; public abstract class Container : Node { Node firstChild; Node lastChild; } }
可以添加到树中的各种对象继承自Node或Container,具体取决于它们是否可以有子项.
通过使Container成为内部类,这意味着它可以访问Node中的私有成员来管理容器的子列表.
这一切都很好.但是现在我希望它能够通用,以便我可以在保持类型安全的同时重用它 – 基本上将所有树功能移动到Node上方的泛型类和Node和Container之间的另一个类.这是我正在尝试做的粗略设计:
public abstract class GenericNode<Node,Container> where Node : GenericNode<Node,Container> where Container : GenericNode<Node,Container>.GenericContainer { Container parent; Node nextNode; Node prevIoUsNode; public abstract class GenericContainer : Node { Node firstChild; Node lastChild; } }
当然,这不起作用,因为您无法使GenericContainer继承自Node(编译器错误CS0689).即使我放弃了内部类的要求(比如,通过使用内部并且只是在我自己的库中小心),我仍然无法找出不会遇到同样问题(和错误)的设计.
(我不认为我会这么做,只是拼出来:我不是在试图“修复”编译错误,也不是在寻找一个简单的树实现.这是一个容器设计问题.)
所以现在我有点难过了.有没有人对如何设计这个东西有更好的想法?
编辑:请务必查看this answer,这是设计的另一个尝试,它试图使用扩展方法来避免将类“注入”继承层次结构的问题(但遗憾的是并不完全有效).
解决方法
遵循扩展方法方法,如果您在接口上定义继承约束(在Node和Container之间),并使用接口装饰容器类,该怎么办?
{ MyNode n = new MyNode(); var c = new MyNode.MyContainer(); c.AddChild(n); MySubNode s = new MySubNode(); c.AddChild(s); OtherNode o = new OtherNode(); o.AddChild(o); //compiler doesn't allow this,as you'd expect: //c.AddChild(o); } public interface IContainer<TContainerType,TNodeType> where TNodeType : GenericNode<TContainerType,TNodeType> where TContainerType : TNodeType,IContainer<TContainerType,TNodeType> { } public static class ContainerExtensions { public static void AddChild<TContainerType,TNodeType>(this IContainer<TContainerType,TNodeType> self,TNodeType node) where TNodeType : GenericNode<TContainerType,TNodeType> where TContainerType : TNodeType,TNodeType> { GenericNode<TContainerType,TNodeType>.AddChild(self as TContainerType,node); } } public class GenericNode<TContainerType,TNodeType> where TContainerType : GenericNode<TContainerType,TNodeType> { TContainerType parent; TNodeType nextNode; TNodeType prevIoUsNode; // Only used by Container TNodeType firstChild; TNodeType secondChild; internal static void AddChild(TContainerType container,TNodeType node) { container.firstChild = node; node.parent = container; } } public class MyNode : GenericNode<MyContainer,MyNode> { } public class MyContainer : MyNode,IContainer<MyContainer,MyNode> { } public class MySubNode : MyNode { } public class OtherNode : GenericNode<OtherNode,OtherNode>,IContainer<OtherNode,OtherNode> { }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。