繁体   English   中英

为什么不能使用比接口中指定的参数类型更通用的参数类型来实现 C# 接口的方法

[英]Why can't one implement a C# interface's method with a more general argument's type than the one specified in the interface

假设我们有一个从其他两个通用接口派生的接口

public interface ISpecificInterface : IGeneralInterfaceA, IGeneralInterfaceB

我们还有另一个接口声明了一个接受上述接口作为参数类型的方法

public interface ISimpleVisitor
{
    void Visit(ISpecificInterface object)
}

我想要的是能够使用ISpecificInterface的祖先之一作为参数的类型来实现该接口的方法。 所以实现只会知道在特定祖先中声明的方法,而不是全部。

public class SimpleVisitor : ISimpleVisitor
{
    public void Visit(IGeneralInterfaceA object)
    {
        object.GeneralInterfaceAMethod();
        object.GeneralInterfaceBMethod(); // This method would not be visible here
    }
}

Intellisense 告诉我这显然是不可能的。
虽然我可以接受它就是这样,但我想知道如果我们向上移动 inheritance 树并且可以确定实现ISpecificInterface的参数肯定实现了IGeneralInterfaceA ,那么这个限制有什么意义?

UPD:也许我表达的意图不够清楚。 我的想法不是强迫用户猜测他可以在那里提供什么类型,而是限制实现只看到它提供的 object 的一部分 用户仍然必须根据接口合同提供实例。

想象一下,有可能实现一个具有更多派生类型的接口方法。 能够做到这一点的目的是什么? 如果您有一个基本接口的客户,他/她根本不知道您的ISpecificInterface

ISimpleVisitor visitor = GetVisitor();
visitor.Visit(new AnotherClass());

由于visitorISimpleVisitor类型,我们不知道实际实现需要ISpecificInterface的事实。 接口是一个契约,没有理由做出假设 当一个接口定义了一个接受IGeneralInterface的方法时,您应该能够提供任何类型的IGeneralInterface ,而不仅仅是一些特定的。 否则,接口的目的——即解耦,在某种程度上是矛盾的。

所以你看,即使我们能够通过更派生的类型来实现接口成员,那也绝对没有

编辑:现在假设我们可以用更抽象的类型实现接口方法:

ISimpleVisitor visitor = GetVisitor();
visitor.Visit(new AnotherClass());

现在ISimpleVisitor期望我们提供ISpecificInterface的实例。 所以客户不知道他/她实际上也可以提供更抽象的东西。 但即使他知道这一点,我们也遇到了问题,因为我们实际上与SimpleVisitor相关联。

ISimpleVisitor visitor = GetVisitor();
visitor.Visit(new MyGeneralVisitor());

虽然这可能会工作一段时间,但一旦GetVisitor返回接口的其他一些实例,它就会中断。

您可以显式地实现接口,同时提供更通用的方法:

public class SimpleVisitor : ISimpleVisitor
{
    void ISimpleVisitor.Visit(ISpecificInterface object) => this.Visit((IGeneralInterface)object);
    public void Visit(IGeneralInterfaceA object)
    {
        object.GeneralInterfaceAMethod();
        object.GeneralInterfaceBMethod(); // This method would not be visible here
    }
}

这使客户端能够提供任何ISpecificInterface实例,而您的代码只关心通用基础接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM