gpt4 book ai didi

c# - LazyInitializer.EnsureInitialized 中的 volatile 局部变量?

转载 作者:太空狗 更新时间:2023-10-30 01:08:41 24 4
gpt4 key购买 nike

我正在查看 Reflector 中的 LazyInitializer.EnsureInitialized(ref T, Func{T}),该方法中似乎有一个 volatile 局部变量 volatile object local1 = s_barrier; .我可以想到两个可能的原因:

  1. .NET 可能会使用给定语言不支持的功能,或者

  2. 实际代码中并没有声明volatile局部变量,但是编译后的代码经过Reflector反编译后,看起来像是volatile局部变量。

有谁知道这里是哪种情况(或者是否有其他解释)?如果是反编译问题,有人知道“真实”代码是什么样子吗?

最佳答案

这看起来像是 Reflector 错误:它只是 s_barrier 字段的正常 volatile 读取。这里没有不能用 C# 表达的“特殊”IL。

 L_000d: volatile. 
L_000f: ldsfld object modreq(System.Runtime.CompilerServices.IsVolatile) System.Threading.LazyInitializer::s_barrier

这只是编译器在读取静态可变字段时发出的正常代码。


这是一个更简单的重现:只需在 release 模式下编译以下内容(包装在一个类型中):

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

更新:这是我对发生的事情的猜测:在 Release模式下,C# 编译器优化了将字段值(volatile 读取的结果)分配给局部变量(STLoc 指令),因为local 随后不再使用。这似乎混淆了 Reflector。如果您更改方法以使用随后的 use local,则确实会发出 STLoc(或类似的)指令,随后 Reflector 的反编译输出看起来很合理。

关于c# - LazyInitializer.EnsureInitialized 中的 volatile 局部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8702335/

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