簡體   English   中英

為什么以接口名為前綴的方法不能在C#中編譯?

[英]Why does a method prefixed with the interface name not compile in C#?

以下為什么不編譯?

interface IFoo
{
void Foo();
}

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

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

編譯器抱怨“當前上下文中不存在名稱'FooMethod'”。

但是,如果將Foo方法更改為:

 public void Foo() { return; }

編譯得很好。

我不明白為什么一個有效,另一個沒有。

因為當您“顯式實現”接口時,您只能通過強制轉換為接口類型來訪問該方法。 隱式轉換將找不到該方法。

void Another()
{
   IFoo f = (IFoo)this:
   f.Foo();
}

進一步閱讀:

C#接口。 隱式實現與顯式實現

嘗試這個:

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

由於您將Foo方法聲明為顯式接口實現 ,因此無法在FooClass的實例上引用它。 您只能通過將FooClass的實例強制轉換為IFoo來引用它。

這種行為確實有很好的理由。 請考慮以下代碼。

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.
}

您在代碼中擁有的內容稱為顯式接口實現。 如果您選擇支持這樣的接口,則類的這些接口方法不是公共的,只能通過適當的接口類型引用(在您的示例中為IFoo)來調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM