温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - What accessibility does an explicitly implemented method have?
c# interface

c# - 明确实现的方法具有什么可访问性?

发布于 2020-03-27 11:40:33

所以我的朋友说,显式实现的接口方法是私有的。

考虑以下示例作为参数:

interface ITest
{
    void Test();
}

class Test : ITest
{
    // IS THIS METHOD PRIVATE?
    void ITest.Test()
    {
        Console.WriteLine("What am I?");
    }
}

我不相信这一点,我将在两边列出论点:

他:

我:

  • You cannot access the Test method from inside the class unless you cast yourself to ITest (which is how explicitly implemented methods work but shouldn't you be able to call the method from inside the class if it really was a private method inside that class?)
  • When you cast a Test-instance to ITest, the Test method becomes publicly available and can be called from anywhere hence it cannot be private.
  • I don't know how credible this is but in this answer it is stated that "explicitly implemented interface member" are public.

I think we both know how Explicit Interface Implementation works and how to use it but right here we aren't sure who's right.
The question really boils down to this:

您可以TestTest类中的方法称为“私有方法”吗?

查看更多

查看更多

提问者
Joelius
被浏览
46
Dmitry Bychenko 2019-07-03 23:32

显式接口方法具有private访问级别。

让我们看一下(在Reflection的帮助下):

  using System.Reflection;

 ...

  var result = typeof(Test)
    .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
    .Select(info => $"{(info.IsPrivate ? "private" : "not private")} {info.Name}");

  string report = string.Join(Environment.NewLine, result);

  Consolw.Write(report);

结果:

private WFA_Junk_4.Form1.ITest.Test // <- Method of interest
not private Equals
not private GetHashCode
not private Finalize
not private GetType
not private MemberwiseClone
not private ToString  

因此,我们无法明确执行它们:

Test test = new Test();

// ITest.Test() call which is OK
(test as ITest).Test();

// Doesn't compile: 
//   1. Private method
//   2. Wrong name; should be typeof(ITest).FullName.Test() which is not allowed 
test.Test(); 

由于我们不能按原样放置方法名称,因此,我可以看到ITest.Test直接调用的唯一方法是反射:

class Test : ITest {
  ...
  public void SomeMethod() 
  {
     // we can't put method's name as it is `SomeNamespace.ITest.Test`
     // Let's find it and execute
     var method = this
       .GetType()
       .GetMethod($"{(typeof(ITest)).FullName}.Test", 
                    BindingFlags.Instance | BindingFlags.NonPublic);

     method.Invoke(this, new object[0]);
  }