【问题标题】:Ensuring parameter types when implementing interface and inheriting在实现接口和继承时确保参数类型
【发布时间】:2023-03-14 17:50:01
【问题描述】:

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

这可能吗?

截取一段短代码:

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

【问题讨论】:

  • 如果可能的话,它可能很难看。例如,如果节点不是节点,您可以抛出异常。但这会提供运行时而不是编译时检查。

标签: c# inheritance interface visibility overload-resolution


【解决方案1】:

您可以通过在节点类型上创建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&lt;Node&gt;SomeNode 实现了INode&lt;SomeNode&gt;,它们是不同的接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2020-03-02
    • 2012-05-16
    • 1970-01-01
    • 2021-03-17
    • 2020-06-17
    相关资源
    最近更新 更多