gpt4 book ai didi

c# - C# Virtual 和 Override 的内部工作原理

转载 作者:太空狗 更新时间:2023-10-29 17:31:30 25 4
gpt4 key购买 nike

关于 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 个类的方法签名)来获取基类或中间派生类的方法。但我想确认并巩固我的理解......

谢谢。

最佳答案

C# 无法做到这一点,但在 IL 中使用 call 而不是 callvirt 实际上可以。因此,您可以使用 Reflection.Emit 解决 C# 的限制。结合 DynamicMethod .

这里有一个非常简单的例子来说明它是如何工作的。如果您真的打算使用它,请将它包装在一个不错的函数中,努力使其适用于不同的委托(delegate)类型。

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));
}

打印:

callvirt, in C#: No.
call, in IL: NO!!!

关于c# - C# Virtual 和 Override 的内部工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/751849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com