为什么这个私有方法会被另一个类执行?

5

我明确地创建和实现了以下接口。

public interface IA
{
    void Print();
}

public class C : IA
{
    void IA.Print()
    {
        Console.WriteLine("Print method invoked");
    }
}

然后执行以下Main方法

public class Program
{
    public static void Main()
    {
        IA c = new C();
        C c1 = new C();
        foreach (var methodInfo in c.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (methodInfo.Name == "ConsoleApplication1.IA.Print")
            {
                if (methodInfo.IsPrivate)
                {
                    Console.WriteLine("Print method is private");
                }
            }
        }
        
        c.Print();
    }
}

控制台上的输出结果如下:

Print方法是私有的

调用了Print方法

那么我的问题是为什么这个私有方法会被其他类执行?

据我所知,私有成员的可访问性仅限于其声明类型,那么为什么它会表现得如此奇怪呢?

1个回答

6
所以我的问题是为什么这个私有方法会从其他类中执行?
嗯,它只是“有点儿”私有。它正在使用 显式接口实现 - 它可以通过接口访问,但只能通过接口访问。所以即使在类 C 内部,如果你有:
C c = new C();
c.Print();

那会编译失败,但是

IA c = new C();
c.Print();

......因为接口是公共的,所以这将在任何地方都起作用。

C#规范(13.4.1)指出,显式接口实现在访问方面是不寻常的:

显式接口成员实现与其他成员具有不同的可访问性特征。由于显式接口成员实现在方法调用或属性访问中永远无法通过其完全限定名称进行访问,因此它们在某种程度上是私有的。但是,由于它们可以通过接口实例进行访问,因此从某种意义上说也是公共的。


那么这是否意味着可访问性限制仅适用于对象的引用而不适用于运行时实例? - Jenish Rabadiya
@JenishRabadiya 不,这意味着您可以将实现整个接口的对象转换为该接口并访问其中不是私有成员的部分:D - Matías Fidemraizer
1
@JenishRabadiya:不确定你的意思是什么...但显式接口实现有点奇怪——我会引用规范的一部分。 - Jon Skeet
1
@JenishRabadiya 我想象你接下来的问题可能是“好吧,为什么你想这样做呢?”。如果是这样的话:https://dev59.com/DG855IYBdhLWcg3w3Ibr - Matthew Watson
1
顺便提一下,还有更奇怪的辅助功能规则:https://dev59.com/3mAh5IYBdhLWcg3wE_xP - Kryptos
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接