如何通过保留方法名来扩展接口?

时间:2012-01-22 18:35:40

标签: c# interface

给出两个接口:

interface I1 {
    int Foo();
}

interface I2 {
    void Foo();
}

一堂课:

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

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

如何通过保留名为I2的方法将I1扩展为Foo

我尝试了以下代码,但它没有编译:

interface I1 {
    int Foo();
}

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

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

3 个答案:

答案 0 :(得分:18)

在示例中不清楚如果允许的话,接口本身将明确声明I2.Foo()将会实现什么。规范(s.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
}

答案 1 :(得分:2)

不太确定你想要它做什么,但你可以这样做: -

public interface I1
{
    int Foo();
}

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

答案 2 :(得分: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;
        }
    }
}