C#虚拟和重写机制如何在内部工作的话题已经在程序员中讨论得死去活来了……但是在谷歌上半小时后,我找不到以下问题的答案(见下文):
使用简单的代码:
public class BaseClass
{
public virtual SayNo() { return "NO!!!"; }
}
public class SecondClass: BaseClass
{
public override SayNo() { return "No."; }
}
public class ThirdClass: SecondClass
{
public override SayNo() { return "No..."; }
}
class Program
{
static void Main()
{
ThirdClass thirdclass = new ThirdClass();
string a = thirdclass.SayNo(); // this would return "No..."
// Question:
// Is there a way, not using the "new" keyword and/or the "hide"
// mechansim (i.e. not modifying the 3 classes above), can we somehow return
// a string from the SecondClass or even the BaseClass only using the
// variable "third"?
// I know the lines below won't get me to "NO!!!"
BaseClass bc = (BaseClass)thirdclass;
string b = bc.SayNo(); // this gives me "No..." but how to I get to "NO!!!"?
}
}
我认为我无法仅使用最派生的实例来访问基类或中间派生类的方法(不修改 3 个类的方法签名)。但我想确认并巩固我的理解......
Thanks.
C# 做不到这一点,但它is实际上可以在 IL 中使用call
代替callvirt
。因此,您可以通过使用来解决 C# 的限制Reflection.Emit结合一个DynamicMethod.
这是一个非常简单的示例来说明其工作原理。如果您确实打算使用它,请将其包装在一个很好的函数中,努力使其能够与不同的委托类型一起使用。
delegate string SayNoDelegate(BaseClass instance);
static void Main() {
BaseClass target = new SecondClass();
var method_args = new Type[] { typeof(BaseClass) };
var pull = new DynamicMethod("pull", typeof(string), method_args);
var method = typeof(BaseClass).GetMethod("SayNo", new Type[] {});
var ilgen = pull.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.EmitCall(OpCodes.Call, method, null);
ilgen.Emit(OpCodes.Ret);
var call = (SayNoDelegate)pull.CreateDelegate(typeof(SayNoDelegate));
Console.WriteLine("callvirt, in C#: {0}", target.SayNo());
Console.WriteLine("call, in IL: {0}", call(target));
}
Prints:
callvirt, in C#: No.
call, in IL: NO!!!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)