这可能是一个愚蠢的问题,但如果我能做到这一点,我真的很好奇。我写了以下示例程序:
class Test1 {
public const int b = 8;
public static int z = 3;
public static void Main(string[] args){
const int q = 6;
Console.WriteLine(q);
Console.WriteLine(b);
Console.WriteLine(z);
}
}
使用mcs
对此进行编译,然后使用monodis
对生成的exe进行反汇编。获得以下代码:
.field public static literal int32 b = int32(0x00000008)
.field public static int32 z
// method line 2
.method public static hidebysig
default void Main (string[] args) cil managed
{
// Method begins at RVA 0x2058
.entrypoint
// Code size 23 (0x17)
.maxstack 8
IL_0000: ldc.i4.6
IL_0001: call void class [mscorlib]System.Console::WriteLine(int32)
IL_0006: ldc.i4.8
IL_0007: call void class [mscorlib]System.Console::WriteLine(int32)
IL_000c: ldsfld int32 Test.Test1::z
IL_0011: call void class [mscorlib]System.Console::WriteLine(int32)
IL_0016: ret
} // end of method Test1::Main
我想使用ldsfld
加载b的值。如果我将IL_0006更改为ldsfld int32 Test.Test1::b
,它将汇编,但是当我运行可执行文件时,我获得了一个删除:
Unhandled Exception:
System.InvalidProgramException: Invalid IL code in Test.Test1:Main
(string[]): IL_0006: ldsfld 0x04000001
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException:
Invalid IL code in Test.Test1:Main (string[]): IL_0006: ldsfld 0x04000001
有没有办法使用static literal
而不是仅使用ldc
?
答案 0 :(得分:6)
您已经从C#视角获得了评论作为答案,但CIL规范更合适也更明确:
I.8.6.1.2位置签名
文字约束承诺该位置的值实际上是内置类型的固定值。该值被指定为约束的一部分。编译器是 需要用其值替换对该位置的所有引用,因此需要VES 不需要为该位置分配空间。这种约束虽然在逻辑上适用于 任何位置,只能放置在复合类型的静态字段上。 字段 如此标记不允许从CIL引用 (它们应与其内容一致 编译时的常量值),但可以使用反射和工具 直接处理元数据。
所以,不,没有办法直接引用那个字段,并且不应该这样。