C# 编译器是否在最终二进制文件中留下重新引用?

问题描述 投票:0回答:1

我有这个代码:

    private static void Tokenize(RichTextLabel Log,string commandString){
        Log.Text += "\n&";
        int[] tokens = new int[5];
        int current = 0;
        while (current < commandString.Length){
            switch (commandString[current]){
            case ' ':
                Log.Text += "+";
                break;
            default:
                Log.Text += "_";
                break;
            }
            current++;
        }
        Log.Text += "\n";
    }

当我查看“编译代码”(骑手的 IL 查看器中的低级 C#)时,我知道它在所有情况下都不是完美或准确的。但这就是它产生的结果:

    private static void Tokenize(RichTextLabel Log, string commandString)
    {
      RichTextLabel richTextLabel1 = Log;
      richTextLabel1.Text = string.Concat(richTextLabel1.Text, "\n&");
      int[] tokens = new int[5];
      for (int current = 0; current < commandString.Length; ++current)
      {
        if (commandString[current] == ' ')
        {
          RichTextLabel richTextLabel2 = Log;
          richTextLabel2.Text = string.Concat(richTextLabel2.Text, "+");
        }
        else
        {
          RichTextLabel richTextLabel3 = Log;
          richTextLabel3.Text = string.Concat(richTextLabel3.Text, "_");
        }
      }
      RichTextLabel richTextLabel4 = Log;
      richTextLabel4.Text = string.Concat(richTextLabel4.Text, "\n");
    }

如你所见,它产生了 4 个重复的

RichTextLabel richTextLabel = Log;
我的问题是,这准确吗?如果是这样,为什么需要多次重新引用该对象?

c# rider low-level decompiler compiler-specific
1个回答
0
投票

这主要是对正在发生的事情的准确表示,只是我认为该变量实际上并不存在。

C# 规范指出:

12.21.4 复合赋值

x «op»= y
形式的操作通过应用二元运算符重载解析 (§12.4.5) 进行处理,就像该操作被编写为
x «op» y
一样。然后,

  • 如果所选运算符的返回类型可以隐式转换为 x 的类型,则该操作将被计算为
    x = x «op» y
    ,除了
    x
    仅计算一次
    (我的粗体)
  • 否则,.....操作将被评估为
    x = (T)(x «op» y)
    ,其中
    T
    x
    的类型,除了
    x
    仅评估一次

并且由于编译器不知道

Log
的作用,为了防止 getter 和 setter 可能引用不同的对象,它只是将其缓存在隐藏变量中。


话虽如此,查看 Sharplab 中生成的 IL 会发现使用了 dup

 操作码,因此它实际上不是将其缓存在变量中,而是将其缓存在堆栈中。因此,Rider 可能只是生成一个变量,以便在伪 C# 中表示相同的语义。不过,效果和性能应该是相同的,并且您不应期望编译器一定会使用一种形式而不是另一种形式。

© www.soinside.com 2019 - 2024. All rights reserved.