显式接口实现不能是虚拟的
作为记录,我已经看到了这个 连接项 但我无法真正理解支持这一点会出现什么问题。
假设我有以下代码:
public interface IInterface
{
void Method();
}
public class Base : IInterface
{
virtual void IInterface.Method()
{
throw new NotImplementedException();
}
}
虚拟标识符有什么问题?拥有 virtual 修饰符可以覆盖
,指示基类中有不同的实现。我现在可以通过删除虚拟方法并创建派生类来使其工作,如下所示:
public class Derived : IInterface
{
void IInterface.Method()
{
throw new NotImplementedException();
}
}
但是这样我实际上根本没有迹象表明我正在重写某些内容。
更新:
根据 C#(部分:20.4.1 显式接口成员实现)规范,有两个原因。
- 隐藏某些方法(我正在使用它)。
- 有 2 个具有相同签名但返回类型不同的函数 (例如对于 IClonable 很有用)。
然而,它没有说明为什么不能使这些方法虚拟化。
更新2:
鉴于答案,我认为我应该在这里重新表述真正的问题。如果以上两个原因是接口显式实现首先成为可能的原因。如果你将一个方法设为虚拟,为什么会出现问题呢?
For the record, I've already seen this connect item but I can't really understand what would be the problem in supporting this.
Say I have the following code:
public interface IInterface
{
void Method();
}
public class Base : IInterface
{
virtual void IInterface.Method()
{
throw new NotImplementedException();
}
}
what is the problem with the virtual identifier? Having a virtual modifier would make it possible to override
indicating there's a different implementation in the base class. I can make it work now by removing the virtual method and creating the derived class like this:
public class Derived : IInterface
{
void IInterface.Method()
{
throw new NotImplementedException();
}
}
however this way I've really no indication at all that I'm overriding something.
Update:
According to the C# (part: 20.4.1 Explicit interface member implementations) spec there are 2 reasons.
- Hiding of certain methods (which I'm using it for).
- Having 2 functions with the same signature but different return types
(usefull for IClonable for example).
It doesn't say anything however about why you can't make these methods virtual.
Update2:
Given the answers I think I should rephrase the real question here. If The above 2 reasons are the reason why explicit implementation of interfaces was made possible in the first place. Why would it be a problem if you make a method virtual.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果只有一个接口被继承,为什么你需要这样做:
为什么不直接去:
If there is only one interface that is being inherited from, why do you need to do:
Why not just go:
我认为原因可以简单地用下面的例子来说明。考虑这段代码:
所以,简而言之,如果您使用相同的方法签名显式实现多个接口,您的派生类将不知道您要重写哪个基方法。
I think the reason can be simply shown in following example. Consider this code:
So, in short, if you explicitly implement multiple interfaces with the same method signature your derived classes will not know which base method you want to override.
显式实现接口的方法具有特殊的可见性范围=除非将“this”强制转换为目标接口类型,否则您无法从其他方法访问它。我想这就是不支持虚拟说明符的原因 - 您无法覆盖不属于普通对象接口(私有/受保护/公共)的方法。
这是我的解决方法:
A method implementating interface explicitly has a special visibility scope = you cannot acces it from another method unless you cast "this" to the target interface type. I suppose it was the reason why virtual specifier is not supported - you cannot override method that is not part of the normal object interface (private/protected/public).
This is my workaround:
,嗯,你确实这样做了,事实上,它显然是一个显式的接口实现。这表明它为接口上指定的方法调用提供多态行为...为什么基类是否也实现了该接口很重要?当你阅读代码时,会对你产生什么影响?
对我来说,声明覆盖的主要好处是确保我确实获得了正确的签名 - 它与我试图覆盖的内容相匹配。您已经通过显式接口实现获得了这种好处,就像您提供了不存在的方法或错误的参数等一样,编译器已经会抱怨。
我可以有点理解你的观点,但我从未发现它是一个实际问题。
Well, you do, sort of - you have the fact that it's clearly an explicit interface implementation. That shows it's providing polymorphic behaviour for that method call which is specified on an interface... why does it matter whether the base class also implemented the interface? What difference will it make to you when you read the code?
To me, the main benefit of stating
override
is to make sure I've really got the right signature - that it matches the thing I'm trying to override. You've already got that benefit with explicit interface implementation, as if you give a non-existent method or the wrong parameters etc, the compiler will already complain.I can sort of see your point, but I've never found it to be an actual problem.
能够将显式接口实现设为虚拟仅在一种情况下有用:当派生类重写需要调用父类实现时。不幸的是,即使可以将显式接口实现虚拟化,如果没有一些新的语法,重写类也无法调用其父类的实现。 VB.net 很好地处理了这个问题,它允许实现接口的方法使用与接口方法不同的名称来声明“受保护”。因此,派生类可以重写受保护的方法(使用适当的名称),并且该重写可以调用父类版本(使用相同的名称)。
Being able to have explicit interface implementations be virtual would be useful in only one scenario: when a derived-class override needs to call the parent-class implementation. Unfortunately, even if explicit interface implementations could be made virtual, there wouldn't be any way for an overriding class to call its parent's implementation absent some new syntax for doing so. VB.net handles this nicely by allowing a method which implements an interface to be declared
Protected
with a different name from the interface's method. A derived class can thus override theProtected
method (using the appropriate name), and that override can call the parent-class version (using the same name).