.NET C# 在父接口中显式实现祖父母接口方法
这个标题很拗口,不是吗?...
这就是我想做的:
public interface IBar {
void Bar();
}
public interface IFoo: IBar {
void Foo();
}
public class FooImpl: IFoo {
void IFoo.Foo() { /* works as expected */ }
//void IFoo.Bar() { /* i'd like to do this, but it doesn't compile */ }
//so I'm forced to use this instead:
void IBar.Bar() { /* this would compile */ }
}
我的问题是...调用 Bar() 不方便:
IFoo myFoo = new FooImpl();
//myFoo.Bar(); /* doesn't compile */
((IBar)myFoo).Bar(); /* works, but it's not necessarily obvious
that FooImpl is also an IBar */
所以...有没有办法声明 < code>IFoo.Bar(){...} 在我的类中,除了基本上将两个接口合并为一个之外?
如果没有,为什么?
That title's a mouthful, isn't it?...
Here's what I'm trying to do:
public interface IBar {
void Bar();
}
public interface IFoo: IBar {
void Foo();
}
public class FooImpl: IFoo {
void IFoo.Foo() { /* works as expected */ }
//void IFoo.Bar() { /* i'd like to do this, but it doesn't compile */ }
//so I'm forced to use this instead:
void IBar.Bar() { /* this would compile */ }
}
My problem with this is that it's... inconvenient to call Bar():
IFoo myFoo = new FooImpl();
//myFoo.Bar(); /* doesn't compile */
((IBar)myFoo).Bar(); /* works, but it's not necessarily obvious
that FooImpl is also an IBar */
So... Is there a way to declare IFoo.Bar(){...}
in my class, other than basically merging the two interfaces into one?
And, if not, why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
可以在接口中使用 new 关键字来显式隐藏在其扩展的接口中声明的成员:
It's possible to use the new keyword in an interface to explicitly hide a member declared in the interface it extends:
您没有两个
IFoo
实现;你只有一个。CLR 不区分来自接口树中不同点的接口副本。
特别是,无法调用
IFoo.Bar()
;您只能调用IBar.Bar
。如果您向
IFoo
添加单独的Bar()
方法,您的代码将正常工作。You don't have two implementations of
IFoo
; you only have one.The CLR does not distinguish between copies of interfaces that come from different points in the interface tree.
In particular, there is no way to call
IFoo.Bar()
; you can only callIBar.Bar
.If you add a separate
Bar()
method toIFoo
, your code will work.由于 IFoo 扩展了 Ibar,因此
void IFoo.Bar()
和void IBar.Bar()
是完全相同的函数。您不能两次定义相同的方法,这就是它不起作用的原因。Since IFoo extends Ibar,
void IFoo.Bar()
andvoid IBar.Bar()
are the exact same function. You cannot define the same method twice, that's why it doesn't work.您希望该行为是什么?每当您调用
IFoo.Bar()
时,它都会使用 IBar 中的定义,因为它只是一个接口,并且没有任何单独的Bar()
概念。您只能在使用new
关键字,此时您要重写类中的方法,而不是实现和接口。当接口相互继承时,子接口几乎没有方法的所有权概念。就好像子接口中声明了两种方法。
警告:潜在的过度并发症和大脑崩溃!!!仔细阅读!!!
我相信这是允许的,如果我错了请纠正我:
为了清楚起见,在类名之前留下了 I,但不再有任何接口。调用的方法取决于对象已转换为哪个类。
哦,您没有使用嵌套接口,它们只是相互继承。嵌套接口是这样的:
正如你所看到的,这是完全不同的。两个接口之间的关系只是一个接口只能在另一个接口内部使用。它们是一个复杂且有些棘手的话题。您可以在此处了解更多信息。 :D
What would you want the behavior to be? Whenever you call
IFoo.Bar()
its going to use the definition in IBar, because its just an interface and has no separate conception ofBar()
whatsoever. You can only have a different method called when casting to a superclass with thenew
keyword, and that's when you are overriding a method in a class, not implementing and interface.When interfaces inherit one another, sub-interfaces have little ownership conception of a method. Its as if the sub-interface has both methods declared in it.
Caution: potential over-complication and brain meltdown!!! Read with caution!!!
I believe this is allowed, correct me if I'm wrong:
left the I's before the class name for clarity, but there are no longer any interfaces. The method that is called will depend on what class the object has been cast to.
Oh, and you're not using nested interfaces, they are just inheriting from one another. Nested interfaces are like this:
As you can see this is completely different. The relationship between the two interfaces is only that one can only be used inside of the other. They are a complicated and somewhat tricky topic. You can read more here. :D
这只是显式实现的接口方法的编译器约定。你可以这样写:
但是如果你想使用显式实现,那么编译器坚持你使用声明该方法的接口的标识符名称。这是有道理的,IFoo 也可以有一个 Bar() 方法。
This is just a compiler convention for explicitly implemented interface methods. You could write it like this:
But if you want to use explicit implementation then the compiler insists you use the identifier name of the interface that declared the method. Which makes sense, IFoo could also have a Bar() method.
我以前也对此感到沮丧,但我认为关键在于,根据定义,它是一个“显式”实现。除非您将对象转换为 IBar,否则对 Bar 方法的任何调用都隐式依赖于该对象最终实现 IBar 的事实。
将下面的示例视为您想要的逻辑结论。理论上,FooImpl 可以通过实现 IFoo 来显式实现 Bar,理论上,派生类(FooChild)可以通过继承 FooImpl 来实现 IBar。问题是,这开辟了(至少)两种不同的模糊“显式”实现路径的可能性:
I've been frustrated by this before, too, but I think the key lies in the fact that it is, by definition, an "explicit" implementation. Unless you're casting your object to IBar, then any invocation of the Bar method is implicitly relying on the fact that the object ultimately implements IBar.
Consider the example below as a logical conclusion to what you want. Theoretically, FooImpl could explicitly implement Bar by virtue of implementing IFoo, and theoretcially, a derived class (FooChild) could implement IBar by virtue of inheriting from FooImpl. The problem is that this opens up a possibility of (at least) two different ambigous "explicit" implementation paths: