在我的项目中,我发现了一个在C#中看起来完全有效的奇怪情况,因为我没有编译错误.
简化示例如下所示:
using System;
using System.Collections.Generic;
namespace Test
{
interface IFoo
{
void FooMethod();
}
class A
{
public void FooMethod()
{
Console.WriteLine("implementation");
}
}
class B : A, IFoo
{
}
class Program
{
static void Main(string[] args)
{
IFoo foo = new B();
foo.FooMethod();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样的代码编译.但是,请注意,A是不是IFoo和B未实现IFoo的方法.在我的情况下,偶然(重构后),A具有相同签名的方法.但是,为什么要A知道如何实现FooMethod的的IFoo接口?A甚至不知道IFoo存在.
对我来说,这样的设计是危险的.因为每次我实现一些接口时,我应检查此接口中的每个方法是否"干扰"基类方法.
如果这是"纯C#功能"?这叫什么?我错过了什么吗?
Mar*_*ell 39
对于接口中的每个成员,编译器只查找显式实现(如果有),然后查找公共实现(隐式实现),即公共API上与接口签名匹配的方法.在这种情况下,A.FooMethod()看起来像公共实现的完美匹配.如果B对该选择不满意,可以是new方法,也可以使用显式实现; 后者将是首选:
void IFoo.FooMethod() { /* explicit implementation */ }
Run Code Online (Sandbox Code Playgroud)
Luk*_*ley 20
这里的关键词是implements.您的基类虽然IFoo对方法签名一无所知,但已经声明了它在您的类层次结构中的某个位置实现接口中的方法.
因此,当您IFoo在派生类中实现时,它已经在类结构中实现了方法签名,因此不需要再次实现它.
如果你有这个:
interface IFoo
{
void FooMethod();
}
class A
{
private void FooMethod(){}
}
class B : A, IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
IFoo在这种情况下,您需要实现,因为IFoo结构在实现时无法访问,正如Mark所说.您可以通过执行IFoo.FooMethod()来隐式实现接口,以确保您具有实现,尽管已在层次结构中定义了适当的方法签名.
Aak*_*shM 11
你在评论中说
FooMethod在A课堂上编写实现的人IFoo实际上是否有可能实现IFoo?
那么,在创作时A思想的作者并不重要A.作者B必须对B从AAND实现继承的事实负责IFoo.作者B要考虑定义的后果B.
你也说
在我的情况下(重构后)
A具有相同签名的方法
暗示这种情况发生在之后A,B并且都写了.在这种情况下,情况会发生变化:当编辑*继承自*(例如A)的类时,编辑负责检查编辑对所有继承类的影响.