实现接口和继承时确保参数类型

时间:2015-09-04 02:22:44

标签: c# inheritance interface visibility overload-resolution

我遇到了类和接口的问题。 我想要实现一个接口声明一个采用所实现类的类型的方法。 当我从这个类继承时,该方法应该只采用继承类的类型。

这可能吗?

一段简短的代码:

class Program
{
    static void Main(string[] args)
    {
        Node node1 = new Node();
        Node node2 = new Node();
        Node node3 = new Node();

        // Connect node2 to node1 and node3 to node1.
        node1.connect(node2)
             .connect(node3);

        SomeNode node4 = new SomeNode();
        SomeNode node5 = new SomeNode();

        node4.connect(node5);

        // node1.connect(node4); // This should not be possible because node1.connect() should only accept Node and not SomeNode.
    }
}

interface INode
{
    int Id { get; set; }

    // Instead of INode, here should be the type of the implementing class or the type of the subclass (or the sub-subclass ...).
    INode connect(INode node); 
}

class Node : INode
{
    public int Id { get; set; }

    // This list MUST be protected and MUST be able to contain only objects of the current class type.
    protected List<Node> connectedNodes; 

    // This should implement the interface mehtod but in subclasses, the type should not be Node but the type of the subclass.
    // Of cause, this method should not be reimplemented in subclasses.
    public Node connect(Node node)
    {
        this.connectedNodes.Add(node);

        return this; // Enable chaining.
    }
}

class SomeNode : Node
{
    // Here should be some additional functionality but NOT the connect() method!
}

1 个答案:

答案 0 :(得分:0)

通过在节点类型上使用INode泛型并为节点使用通用基类,您可以基本上获得所描述的内容。通用节点类型将用于允许单个实现使用不同类型

interface INode<TNode> {
    int Id { get; set; }
    TNode connect(TNode node); 
}

abstract class NodeBase<TNode> : INode<TNode> {
    public int Id { get; set; }
    protected List<TNode> connectedNodes; 

    public TNode connect(TNode node) {
        this.connectedNodes.Add(node);
        return this; // Enable chaining.
    }
}

class Node : NodeBase<Node> { }

class SomeNode : NodeBase<SomeNode> { }

但是,这会创建一个与您的问题不同的继承结构。 SomeNode {}不再来自Node,因此Node n = new SomeNode()不再具有价值。它们也不再共享一个界面。 Node实现INode<Node>SomeNode实现INode<SomeNode>,它们是不同的接口。