2012-01-22 52 views
3

考慮兩個接口:如何通過保留方法名稱來擴展接口?

interface I1 { 
    int Foo(); 
} 

interface I2 { 
    void Foo(); 
} 

和A類:

class Test : I1, I2 { 
    int I1.Foo() { 
     Console.WriteLine("I1.Foo"); 
     return default(int); 
    } 

    public void Foo() { 
     Console.WriteLine("I2.Foo"); 
    } 
} 

我如何通過保持命名Foo的方法擴展與I1接口I2

我試着下面的代碼,但它不會編譯:

interface I1 { 
    int Foo(); 
} 

interface I2 : I1 { 
    void I2.Foo(); 
} 

class Test : I2 { /* same code */ } 
+4

你不能在接口中實現* anything *。只允許聲明。 –

+0

這不是非常有用,但肯定是允許的。您將希望避免使用相同的成員名稱,這使得類難以實現該界面並讓任何人使用它。 –

回答

17

它是什麼在接口明確聲明I2.Foo()本身是否被允許將完成的例子不清楚。規範(第13.4.1節)允許實現接口的結構或類聲明顯式成員實現。 (接口不能聲明任何實現,顯式或其他)。

因此,假設我們已經定義:

interface IFoo 
{ 
    void Bar(); 
} 

interface IBaz : IFoo 
{ 
    new void Bar(); 
} 

interface IQux : IBaz { } 

class A : IQux // equivalent to class A : IQux, IBaz, IFoo (spec sec. 13.4.6) 
{ 
    void IFoo.Bar() 
    { 
     Console.WriteLine("IFoo.Bar"); 
    } 

    void IBaz.Bar() 
    { 
     Console.WriteLine("IBaz.Bar"); 
    } 

    public void Bar() 
    { 
     Console.WriteLine("A.Bar"); 
    } 

    // Not allowed: void IQux.Bar() {...} 
    // Since "The fully-qualified name of the interface member 
    // must reference the interface in which the member 
    // was declared" (s. 13.4.1) 
} 

然後將下面的驅動程序顯示了顯式接口方法實現的效果。

public static void Main() 
{ 
    A a = new A(); 
    a.Bar(); // prints A.Bar 
    (a as IFoo).Bar(); // prints IFoo.Bar 
    (a as IBaz).Bar(); // prints IBaz.Bar 
    (a as IQux).Bar(); // prints IBaz.Bar 
} 
+2

這是迄今爲止最完整和最好的答案。 –

2

不太清楚你想要它做的事情,但你可以這樣做: -

public interface I1 
{ 
    int Foo(); 
} 

public interface I2:I1 
{ 
    new void Foo(); 
} 
0

它僅如果這兩種方法具有不同的簽名,這意味着它們必須具有不同數量的參數或不同類型的參數或兩者。

爲什麼不說出你的兩種方法GetFooDoFoo

這會工作

public interface I1 
{ 
    int Foo(); 
} 

public interface I2 : I1 
{ 
    void Foo(int i); 
} 

這也將工作

public interface I1 
{ 
    int GetFoo(); 
} 

public interface I2 : I1 
{ 
    void DoFoo(); 
} 

你也可以聲明一個屬性。屬性由兩個方法組成:一個getter和一個setter。

public interface I 
{ 
    int Foo { get; set; } 
} 

public class C : I 
{ 
    private int _foo; 
    public int Foo 
    { 
     get { 
      // getter 
      return _foo; 
     } 
     set { 
      // setter 
      _foo = value; 
     } 
    } 
}