[英]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());
由于visitor
是ISimpleVisitor
类型,我们不知道实际实现需要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.