2010-07-27 19 views
6

爲什麼下面不能編譯?爲什麼用C#編譯前綴的接口名稱的方法?

interface IFoo 
{ 
void Foo(); 
} 

class FooClass : IFoo 
{ 
void IFoo.Foo() { return; } 

void Another() { 
    Foo(); // ERROR 
} 
} 

編譯器會抱怨「名稱'FooMethod'在當前上下文中不存在」。

但是,如果Foo中的方法更改爲:

public void Foo() { return; } 

這個編譯就好了。

我不明白爲什麼一個人工作,而另一個不工作。

回答

2

試試這個:

void Another() { 
    ((IFoo)this).Foo(); 
} 

既然你聲明Foo中的方法作爲explicit interface implementation,你不能引用它FooClass的一個實例。您只能通過將FooClass的實例投射到IFoo來引用它。

0

您在代碼中有所謂的顯式接口實現。如果您選擇支持這樣的接口,那麼您的類的這些接口方法不是公共的,只能通過適當的接口類型引用(在您的示例中爲IFoo)調用。

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. 
} 
相關問題