gpt4 book ai didi

C# 编译优化 : null coalescing operator - UPDATED - Reflector's bug?

转载 作者:太空宇宙 更新时间:2023-11-03 14:25:12 25 4
gpt4 key购买 nike

您好!我对 C# 编译器如何执行其优化感到有些困惑。
我已经编写了以下 getter 来弥补“惰性”初始化和 null 情况下的默认值:

静态类助手:

private static string host;  
public static string Host
{
get
{
return host ?? (host= (ConfigurationManager.AppSettings["Host"] ?? "host.ru"));
}
}

Reflector反汇编结果如下:

public static string Host 
{
get
{
if (Helper.host == null)
{
string host = Helper.host;
}
return (Helper.host = ConfigurationManager.AppSettings["Host"] ?? "host.ru");
}
}

看起来它会以不同于假设的其他方式工作......

更新

    private static string host;
public static string Host
{
get
{
return host ?? (host = (GetVal() ?? "default"));
}
}
static void Main(string[] args)
{

Console.WriteLine(Host);
host = "overwritten";
Console.WriteLine(Host);
}
static string GetVal()
{
return "From config";
}

工作正常(来自配置,被覆盖),但 Reflector 显示相同:

public static string Host
{
get
{
if (Program.host == null)
{
string host = Program.host;
}
return (Program.host = GetVal() ?? "default");
}
}

最佳答案

这看起来像是 Reflector 的 C# 反汇编中的错误。

从这段代码开始:

public static string _test;
public static string _setting;

public static string Test_1
{
get { return _test ?? (_setting ?? "default"); }
}

Reflector 显示此 C# 反汇编:

public static string Test_1
{
get
{
return (_test ?? (_setting ?? "default"));
}
}

和相应的IL:

.method public hidebysig specialname static string get_Test_1() cil managed
{
.maxstack 8
L_0000: ldsfld string ConsoleApplication1.Program::_test
L_0005: dup
L_0006: brtrue.s L_0017
L_0008: pop
L_0009: ldsfld string ConsoleApplication1.Program::_setting
L_000e: dup
L_000f: brtrue.s L_0017
L_0011: pop
L_0012: ldstr "default"
L_0017: ret
}

我不是 IL 专家,但这是我的看法:

  • L_0000: ldsfld _test进入评估堆栈
  • L_0005: dup 复制计算堆栈最顶层的值 ( _test ) 并将其压入堆栈。
  • L_0006: brtrue.s 弹出 dup 创建的值离开堆栈并跳转到 L_0017如果不是 null .
  • L_0008: pop 此时,_testnull , 所以将该值从堆栈中弹出。

它继续评估 _setting以类似的方式,最终返回"default"如果_setting也是null .

现在,如果我们像这样在代码中添加一个赋值:

public static string Test_2
{
get { return _test ?? (_test = (_setting ?? "default")); }
}

Reflector 显示此 C# 反汇编:

public static string Test_2
{
get
{
if (_test == null)
{
string text1 = _test;
}
return (_test = _setting ?? "default");
}
}

这是不正确的(如果 _test 不是 null,它不会返回 _test,而是将 _setting"default" 分配给 _test,然后返回)。

但是,IL 反汇编看起来像 Test_1 的 IL , 在 L_0017 有一些额外的说明和 L_0018做作业。

.method public hidebysig specialname static string get_Test_2() cil managed
{
.maxstack 8
L_0000: ldsfld string ConsoleApplication1.Program::_test
L_0005: dup
L_0006: brtrue.s L_001d
L_0008: pop
L_0009: ldsfld string ConsoleApplication1.Program::_setting
L_000e: dup
L_000f: brtrue.s L_0017
L_0011: pop
L_0012: ldstr "default"
L_0017: dup
L_0018: stsfld string ConsoleApplication1.Program::_test
L_001d: ret
}

最后,如果您复制 Reflector 的 C# dissembly 并针对原始版本运行它,您会看到它产生了不同的结果。

using System;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
_test = "Test";
Console.WriteLine(Test_2);
Console.WriteLine(Reflector_Test_2);
Console.ReadLine();
}

public static string _test;
public static string _setting;

public static string Test_1
{
get { return _test ?? (_setting ?? "default"); }
}

public static string Test_2
{
get { return _test ?? (_test = (_setting ?? "default")); }
}

public static string Reflector_Test_2
{
get
{
if (_test == null)
{
string text1 = _test;
}
return (_test = _setting ?? "default");
}
}
}
}

输出

Test
default

关于C# 编译优化 : null coalescing operator - UPDATED - Reflector's bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4292142/

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