所以我的朋友说,显式实现的接口方法是私有的。
考虑以下示例作为参数:
interface ITest
{
void Test();
}
class Test : ITest
{
// IS THIS METHOD PRIVATE?
void ITest.Test()
{
Console.WriteLine("What am I?");
}
}
我不相信这一点,我将在两边列出论点:
他:
我:
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?) Test
-instance to ITest
, the Test
method becomes publicly available and can be called from anywhere hence it cannot be private. 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:
您可以Test
将Test
类中的方法称为“私有方法”吗?
显式接口方法具有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]);
}
谢谢,这几乎是我想要的。您是否偶然知道为什么
test.Test()
在这种情况下不被允许this.Test()
与Test
全班同学一样?当然,如果它只是私人的,您应该能够做到这一点?同样,如果您尝试调用它,
test.Test()
则会得到'Demo.Test' does not contain a definition for 'Test' and no extension method 'Test' accepting a first argument of type 'Demo.Test' could be found (are you missing a using directive or an assembly reference?)
编译器错误。但是,如果尝试调用显式指定为private的方法,则会得到'Demo.Test.PrivateMethod()' is inaccessible due to its protection level
。为什么第一种情况与第二种情况不一样?这两种错误在第一种情况下都是准确的吗?@Joelius:不仅我们可以
private
访问,而且方法的名称阻止我们直接调用它;我看到的显式调用它的唯一方法(不强制转换为接口)是反射@DmitryBychenko无法从类内部调用该方法的事实是您知道它不是私有的。如果它是私有的,则可以调用它。您不能说它完全不像私有方法那样发挥作用的许多方法是使它私有化的原因。
关于最后一个使用反射的代码示例,为什么不像通常那样通过将引用(
this
在这种情况下)转换为接口类型来像通常那样调用Test()呢?基本上就像您在第二个代码段中所做的那样:(public void SomeMethod() { ((ITest) this).Test(); }
也许我误解了您在上一个代码示例中试图显示的内容……)