为什么不允许在派生接口上明确地实现基接口的方法?

时间:2016-01-21 16:13:28

标签: c# inheritance interface

这是一个简单的例子来解释我的问题 - 我试图通过将通用接口派生到具有如下具体类型的接口来提高明确实现的通用接口的代码可读性:interface ITyped : IGeneric<string>。我们的想法是不必在所有已实现的显式方法名称中使用IGeneric<string>

所以代码如下:

ITyped.M1(string p){}
ITyped.M2(string p){} 

而不是

IGeneric<string>.M1(string p){}
IGeneric<string>.M2(string q){}

想象一下具有多种泛型类型的界面,以了解我为什么要这样做。

现在的事情是:这不会起作用!编译器抛出一个错误,我的声明不是接口的成员。我必须明确地使用带有泛型声明的基接口。如果这有用的话会不会有意义?进一步的尝试表明,甚至不需要泛型 - 简单的派生接口也不允许在派生接口中明确地实现基接口的继承方法。我想理解为什么它不被允许的理论。

是否有其他方法可以提高此方案的可读性?

此处填写示例代码:

interface IGeneric<T>
{
    void M(T t);
}

interface ITyped: IGeneric<string> { }

class C : ITyped
{
    //Explicit declaration with base interface - OK
    void IGeneric<string>.M(string t) {}

    //Implicit declaration - OK
    public void M(string t){ }

    //Explicit declaration with derived interface - Error!
    void ITyped.M(string t) {} //Error CS0539   

}

2 个答案:

答案 0 :(得分:2)

在提示c#语言规范和CodesInChaos对另一个答案的评论后,我找到了一个不允许的原因:

想象一下第二个派生接口IDerived2: IBase和一个可以实现两个派生接口的具体类,我能够创建两个不明确的实现

private interface IBase
{
    void M();
}

class C : IDerived1, IDerived2
{
    //Which method should now be called when using IBase.M?
    void IDerived1.M() {} 
    void IDerived2.M() {}  
}

因此,它是多继承,它限制我们使用派生的显式接口声明。通过强制使用基本声明,在多继承的情况下,编译器确保只能有一个实现,从而有效地阻止我们做坏事。

解决方法是明确地实现接口但是隐含地执行它 - 实际上我明确地做了它的另一个原因,但一般来说,隐式声明将是一个有效的解决方法。 / p>

答案 1 :(得分:-2)

你可以这样做:

IGeneric<string> x = new C();

如果C未从IGeneric<T>实施M,则无法保持该类可从该类分配。