用于访问只读字段的 MSIL 代码生成 ldarg.0
本文关键字:代码生成 ldarg MSIL 访问 读字段 用于 | 更新日期: 2023-09-27 18:31:57
我在 C# 中有一个简单的方法可以访问只读字段:
IL_0024: ldarg.0
IL_0025: ldfld string MyAssembly.MyClass.TestClass::A
我的自然假设是,这用于在访问成员字段时加载"this"引用,并且此问题也证实了:为什么在 MSIL 中调用字段之前必须执行 ldarg.0?
但是,ldarg 的文档提到它用于加载传递给方法的参数。
这种行为的正确解释是什么?以及如何区分加载"this"引用和将第一个形式参数加载到IL中的方法?
两者都是正确的:)
this
值作为第一个"不可见"参数传递给实例方法,因此在实例方法中,ldarg.0
是"加载this
值"。
如果编写使用不同参数的方法,则可以看到差异。例如:
static void StaticMethod(int x)
{
// This uses ldarg.0
Console.WriteLine(x);
}
void InstanceMethod(int x)
{
// This uses ldarg.1
Console.WriteLine(x);
}
以及如何区分加载"this"引用和将第一个形式参数加载到 IL 中的方法?
通过检查上述内容,基本上 - 如果它是一个实例方法,那么ldarg.0
加载隐式this
值。否则,它将加载第一个形式参数值。
所有实例方法都采用第一个参数作为类实例本身。这是隐式完成的,因此在调用方法时不必传递它。
鉴于this
是一个方法参数,您需要使用 ldarg.0
将this
实例推送到评估堆栈。