Dan*_*mov 4 .net c# mono c#-5.0 methodaccessexception
我已A.Test()声明public virtual并B.Test()声明为private new.
我是base.Test()从C那个继承人那里打来的B.
此代码使用Mono 2.10.2编译但抛出MethodAccessException:
class A {
public virtual void Test () { }
}
class B : A {
private new void Test () { }
}
class C : B {
public C ()
{
base.Test ();
}
public static void Main (string[] args)
{
var c = new C ();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的例外:
System.MethodAccessException: Method TestBug.B:Test () is inaccessible from method TestBug.C:.ctor ()
这是正确的行为吗?
这是在Microsoft .NET中编译还是使用较新版本的Mono编译?
C#规范对此有何看法?
它是否随C#版本而变化?
Jon*_*eet 12
它是有效的C#,但Mono 2.10.2编译器显然做错了.使用MS编译器,调用将base.Test()编译为:
IL_0008: ldarg.0
IL_0009: call instance void A::Test()
Run Code Online (Sandbox Code Playgroud)
Mono 3.0.6.0编译器的工作方式相同.
就A目前而言,B.Test()实际上并不存在.
实际上,C#5规范的第3.7节甚至给出了一个与你的非常类似的明确示例:
新成员的声明仅在新成员的范围内隐藏继承的成员.
Run Code Online (Sandbox Code Playgroud)class Base { public static void F() {} } class Derived: Base { new private static void F() {} // Hides Base.F in Derived only } class MoreDerived: Derived { static void G() { F(); } // Invokes Base.F }在上面的示例中,Derived中的F声明隐藏了从Base继承的F,但由于Derived中的新F具有私有访问权限,因此其范围不会扩展到MoreDerived.因此,MoreDerived.G中的调用F()是有效的并将调用Base.F.
我强烈怀疑Mono 2.10.2盲目地插入一个调用B.Test()- 不是因为它看到了私有方法的存在,而只是为了确保"调用基类方法".碰巧的是,这在执行时非常糟糕.选择调用哪个基类方法是一个有趣的方法,B 可以在C的编译时和执行时间之间进行更改,以覆盖Test()...此时行为是不明显的.Eric Lippert在一篇你可能感兴趣的博客文章中谈到这一点.
| 归档时间: |
|
| 查看次数: |
295 次 |
| 最近记录: |