加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在C#中创建一个侵入式树类使用泛型?

发布时间:2020-12-15 21:11:27 所属栏目:百科 来源:网络整理
导读:在C#中,我有一个看起来像这样的侵入式树结构: public abstract class Node{ Container parent; Node nextNode; Node previousNode; public abstract class Container : Node { Node firstChild; Node lastChild; }} 可以添加到树中的各种对象继承自Node或Co
在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>
{
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读