实现具有冲突方法签名的接口的类

时间:2013-05-31 18:41:26

标签: c# interface clr

假设我们有两个具有冲突方法签名的接口:

interface IA
{
    void F();
}

interface IB
{
    int F();
}

现在我们创建一个这样的类:

class Test : IA, IB
{
    public void F() { ... }
    int IB.F() { ... }
}

名为IB.F的方法看起来像private方法,但您可以执行以下操作:

var t = new Test();
t.F();       //Calls public method F
((IB)t).F(); //Calls private method IB.F!!!

所以我的问题是: C#编译器如何知道可以在类范围外调用IB.F

我猜这是IB.前缀,但查看了IL代码,它只显示为带有奇怪签名的private方法。

2 个答案:

答案 0 :(得分:9)

“private”方法包含以下内容:

.method private hidebysig newslot virtual final instance int32 ns.IB.F() cil managed
{ 
    .override Tests.IB::F
    //...
}

IB

.method public hidebysig newslot abstract virtual instance int32 F() cil managed
{
}

.override告诉编译器查看IB中的声明。它说方法是public

该方法实际上没有声明private,默认情况下,“nothing”对于接口方法来说意味着public

尝试在int IB.F()前添加任何类型的访问修饰符,这将是编译器错误,因为您可能无法更改显式接口实现的可访问性。

答案 1 :(得分:2)

看起来像

的方法
int IB.F() { ... }

即。名称中有一个点.,并且(最后一个)点之前的名称部分是接口名称,不是普通的实例方法。这是一个所谓的 显式接口实现

不要将其视为通常的private方法。请注意,将C#关键字private与显式接口实现一起使用甚至是不合法的。

从某种意义上说,这种方法具有它实现的接口的可访问性。

因此,只要有人拥有该类的实例,就可以调用它来转换为接口。

例如,在MSDN网站上,他们不会记录班级的internalprivate成员。但是他们文档显式接口实现(接口在程序集外部可见),因为这些成员可以从外部调用(即由我们调用)。有关示例,请参阅List<T> Class