为什么以下不能编译?
interface IFoo
{
void Foo();
}
class FooClass : IFoo
{
void IFoo.Foo() { return; }
void Another() {
Foo(); // ERROR
}
}
编译器抱怨“当前上下文中不存在名称'FooMethod'”。
但是,如果将Foo方法更改为:
public void Foo() { return; }
这个编译得很好。
我不明白为什么一个有效,另一个没有。
答案 0 :(得分:10)
因为当您“显式实现”接口时,您只能通过强制转换为接口类型来访问该方法。隐式投射将找不到该方法。
void Another()
{
IFoo f = (IFoo)this:
f.Foo();
}
进一步阅读:
C# Interfaces. Implicit implementation versus Explicit implementation
答案 1 :(得分:2)
试试这个:
void Another() {
((IFoo)this).Foo();
}
由于您将Foo方法声明为explicit interface implementation,因此无法在FooClass的实例上引用它。您只能通过将FooClass的实例强制转换为IFoo来引用它。
答案 2 :(得分:1)
这种行为确实有很好的理由。请考虑以下代码。
public interface IA
{
IA DoSomething();
}
public interface IB
{
IB DoSomething();
}
public class Test : IA, IB
{
public IA DoSomething() { return this; }
IA IA.DoSomething() { return this; }
IB IB.DoSomething() { return this; }
}
在这种情况下,Test
类必须至少实现一个DoSomething
方法,因为声明具有相同签名的两个不同方法是不合法的。如果您要检查IL,您会看到显式实现接口会自动修饰成员名称,以便同一个类中不存在两个具有相同名称的成员。并且为了能够调用上面3种不同的DoSomething
变体中的每一种,您必须从正确类型的引用中调用该成员。这就是编译器知道绑定到正确成员的方式。
public static void Main()
{
var test = new Test();
test.DoSomething(); // Compiler binds to the implicit implementation.
var a = (IA)test;
a.DoSomething(); // Compiler binds to the IA implementation.
var b = (IB)test;
b.DoSomething(); // Compiler binds to the IB implementation.
}
答案 3 :(得分:0)
您的代码中包含的内容称为显式接口实现。如果你选择支持这样的接口,你的类的这些接口方法不是公共的,只能通过适当的接口类型引用调用(在你的例子中是IFoo)。