为了记录,我已经看过这个connect item,但我不能真正理解支持这个问题会是什么。
说我有以下代码:
public interface IInterface
{
void Method();
}
public class Base : IInterface
{
virtual void IInterface.Method()
{
throw new NotImplementedException();
}
}
虚拟标识符有什么问题?拥有虚拟修饰符可以使override
表明基类中有不同的实现。我现在可以通过删除虚方法并创建这样的派生类来使其工作:
public class Derived : IInterface
{
void IInterface.Method()
{
throw new NotImplementedException();
}
}
然而,这种方式我根本没有迹象表明我压倒了什么。
更新
根据C#(部分:20.4.1显式接口成员实现)规范,有两个原因。
但是没有说明为什么你不能将这些方法虚拟化。
UPDATE2:
鉴于答案我认为我应该在这里重新提出真正的问题。如果以上两个原因是首先使接口的显式实现成为可能的原因。如果将方法设为虚拟,为什么会出现问题?
答案 0 :(得分:14)
实现接口的方法显式具有特殊的可见范围=除非将“this”转换为目标接口类型,否则无法从其他方法访问它。我想这就是为什么不支持虚拟说明符的原因 - 你不能覆盖不属于普通对象接口(private / protected / public)的方法。
这是我的解决方法:
public class Base : IInterface
{
protected virtual void Method()
{
}
void IInterface.Method()
{
this.Method()
}
}
public class Derived : Base
{
protected override void Method()
{
}
}
答案 1 :(得分:7)
然而,这种方式我根本没有迹象表明我压倒了什么
嗯,你确实如此 - 事实上它显然是一个明确的接口实现。这表明它为在接口上指定的方法调用提供了多态行为...为什么基类还是否实现了接口?阅读代码时,它会给你带来什么不同?
对我来说,陈述override
的主要好处是确保我确实得到了正确的签名 - 它与我试图覆盖的东西相匹配。您已经通过显式接口实现获得了这些好处,就好像您提供了一个不存在的方法或错误的参数等,编译器已经抱怨了。
我可以排序看到你的观点,但我从来没有发现它是一个真正的问题。
答案 2 :(得分:0)
如果只有一个继承的接口,为什么需要这样做:
public class Base : IInterface
{
virtual void IInterface.Method()
{
throw new NotImplementedException();
}
}
为什么不去:
public class Base : IInterface
{
virtual void Method()
{
throw new NotImplementedException();
}
}
答案 3 :(得分:0)
能够将显式接口实现设置为虚拟只在一种情况下有用:当派生类覆盖需要调用父类实现时。不幸的是,即使显式接口实现可以变为虚拟,也不会有任何方法让覆盖类调用其父实现而没有一些新的语法。 VB.net通过允许实现接口的方法声明Protected
并使用与接口方法不同的名称来处理这个问题。派生类因此可以覆盖Protected
方法(使用适当的名称),并且该覆盖可以调用父类版本(使用相同的名称)。
答案 4 :(得分:-1)
我认为原因可以在下面的例子中简单地显示出来。请考虑以下代码:
public interface IInterfaceA
{
void Method();
}
public interface IInterfaceB
{
void Method();
}
public class Base : IInterfaceA, IInterfaceB
{
virtual void IInterfaceA.Method()
{
...
}
virtual void IInterfaceB.Method()
{
...
}
}
public class Derived : Base
{
public override void Method()
{
// Will this override IInterfaceA or IInterfaceB implementation???
}
}
因此,简而言之,如果您使用相同的方法签名显式实现多个接口,则派生类将不知道您要覆盖哪个基本方法。