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



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

这可能吗?

截断的短代码:

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!
}

您可以通过使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>,它们是不同的接口。

最新更新