我在看LazyInitializer.EnsureInitialized(ref T, Func{T})
在 Reflector 中,该方法中似乎有一个易失性局部变量volatile object local1 = s_barrier;
。我可以想到两个可能的原因:
.NET 可能会使用给定语言不支持的功能,或者
实际代码并没有声明一个 volatile 局部变量,但是当编译后的代码被 Reflector 反编译时,它看起来像一个 volatile 局部变量。
有谁知道这里是哪种情况(或者是否可能有其他解释)?如果这是反编译的问题,有谁知道“真实”代码会是什么样子?
这看起来像一个 Reflector bug:它只是一个普通的易失性read of the s_barrier
场地。这里没有不能用 C# 表达的“特殊”IL。
L_000d: volatile.
L_000f: ldsfld object modreq(System.Runtime.CompilerServices.IsVolatile) System.Threading.LazyInitializer::s_barrier
这只是编译器在读取静态易失性字段时发出的正常代码。
这是一个更简单的重现:只需编译以下内容(包装在类型中)即可release mode:
private static volatile object field;
private static void Main()
{
var temp = field;
}
Reflector 生成以下反编译的 C#:
private static void Main()
{
volatile object field = Program.field;
}
当 IL 实际上是:
L_0000: volatile.
L_0002: ldsfld object modreq([mscorlib]System.Runtime.CompilerServices.IsVolatile) WindowsFormsApplication1.Program::field
L_0007: pop
L_0008: ret
UPDATE:
以下是我对所发生情况的猜测:在发布模式下,C# 编译器优化了将字段值(易失性读取的结果)分配给局部变量(stloc
指令),因为随后不会使用本地。这似乎让 Reflector 感到困惑。如果您将方法更改为使用后续的 use local,则stloc
(或类似的)指令确实会被发出,随后来自 Reflector 的反编译输出看起来是合理的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)