gpt4 book ai didi

c# - 通过动态方法获取静态字段的值

转载 作者:太空宇宙 更新时间:2023-11-03 11:19:40 26 4
gpt4 key购买 nike

我有以下类(class):

public class TestClass
{
public static readonly string HELLO = "Hello, ";

public static string SayHello(string name)
{
return HELLO + name;
}
}

我想通过 DynamicMethod 访问 HELLO 的静态字段。使用 GetValue 的标准反射有效:

public static string GetViaInvoke()
{
Type tcType = typeof(TestClass);
FieldInfo fi = tcType.GetField("HELLO");
string result = fi.GetValue(null) as string;
return result;
}

但我需要类似的东西(OpCodes 来自类似方法的 ILDasm):

public static string GetViaDynamicMethod()
{
Type tcType = typeof(TestClass);
FieldInfo fi = tcType.GetField("HELLO");

DynamicMethod dm = new DynamicMethod("getHello", typeof(string), Type.EmptyTypes);
ILGenerator iL = dm.GetILGenerator();

iL.DeclareLocal(typeof(string));
iL.Emit(OpCodes.Nop);
iL.Emit(OpCodes.Ldsfld, fi);
iL.Emit(OpCodes.Stloc_0);
iL.Emit(OpCodes.Br_S, 0x09);
iL.Emit(OpCodes.Ldloc_0);
iL.Emit(OpCodes.Ret);

Func<string> fun = dm.CreateDelegate(typeof(Func<string>)) as Func<string>;
string result = fun();
return result;
}

这个想法非常简单,动态方法可以很好地处理非静态字段(ldfld 操作码和 this 对象),但是当我尝试访问静态字段时,我收到异常:

System.InvalidProgramException was unhandled
Message=InvalidProgramException

最佳答案

基于执行相同操作的反编译代码编写的 IL 代码是个好主意,但您仍然需要了解自己在做什么。

如果你看the documentation for Br_S ,您会看到您应该将它与 Label 一起使用,而不是 int。我认为您代码中的 Br_S 分支到字节偏移量 9 处的一条指令,但我不知道那是哪条指令,您永远不应该编写这样的代码。

如果你只想加载静态字段的值并返回它,你不需要任何局部变量或分支。以下就足够了:

iL.Emit(OpCodes.Ldsfld, fi);
iL.Emit(OpCodes.Ret);

它所做的是将值加载到计算堆栈上,然后立即返回。它有效,因为当您从一个确实返回值的方法返回时,评估堆栈上的单个值将用作该返回值。

关于c# - 通过动态方法获取静态字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11449014/

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