7

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

interface IA
{
    void F();
}

interface IB
{
    int F();
}

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

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

名为 as 的方法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带有奇怪签名的方法出现。

4

2 回答 2

9

“私有”方法包含以下内容:

.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,默认情况下“无”表示public接口方法。

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

于 2013-05-31T18:47:01.333 回答
2

一个看起来像的方法

int IB.F() { ... }

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

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

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

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

例如,在 MSDN 站点上,它们不记录类internalprivate类成员。但是它们确实记录了显式接口实现(接口在程序集外部可见),因为这些成员可以从外部(即我们)调用。有关示例,请参见List<T>类。

于 2013-05-31T19:14:51.920 回答