C# 代码中的内联注释是否会影响已编译的 dll?



考虑一个内容很少的 C# 文件,例如

...
public void DoSomething()
{
Console.WriteLine("Does Something!");
}
...

以及带有注释的相同片段:

...
public void DoSomething()
{
// This line does something!
Console.WriteLine("Does Something!");
}
...

当编译器出现将此文件放入dll中时,它将删除多余的文件并使其机器可读。这是否意味着两个 dll 是完全相同的?这两个文件显然具有不同的行数,并且会散列到不同的值,但编译器是否关心?空行是否具有与更改文件相同的影响,例如

...
public void DoSomething()
{
Console.WriteLine("Does Something!");
}
...

这是否意味着两个 dll 是完全相同的?

或。这里有一点微妙之处。

  • 默认情况下,C# 编译器不是确定性的。也就是说,即使使用完全相同的输入,由于生成的 ID,您也可能获得不同的 DLL。我知道有人推动将确定性模式作为 .NET Core SDK 项目的默认设置,但我不确定这是否发生了。从命令行中,只需使用 Roslyn 2.8.0.62830 运行 csc,deterministic不是默认值
  • 行号通常不会影响 IL,但它们会影响正在生成的任何 PDB 文件,以便调试器知道源代码中的哪一行与哪个 IL 相对应。即使行号没有更改,PDB 文件也包含源代码的哈希,以便调试器可以检查它是否正在查看"正确"的代码。
  • 由于调用方信息属性,行号无论如何都会产生影响,如下面的代码所示:

    using System;
    using System.Runtime.CompilerServices;
    class Program
    {
    public static void Main()        
    {
    // Remove this comment and get a different result
    PrintLine();
    }
    static void PrintLine([CallerLineNumber] int line = 0)
    {
    Console.WriteLine(line);
    }
    }
    

有了评论,这打印了 9。如果没有注释,它将打印 8。IL 是不同的,因为行号作为常量嵌入在那里。

如果您担心评论会影响性能,那么您绝对不应该这样做。但是,如果你真的担心仅仅通过进行通常不会影响行为的改变是否可能进行任何改变 - 是的,可能会有微妙的变化。

我使用SharpLab为您检查(尽管我已经知道注释不会影响生成的IL(。

public void Main()
{
// Useful comment
Console.WriteLine("Hello world!");
}

public void Main()
{
/* Useful comment */ Console.WriteLine("Hello world!");
}

两者都编译为

public void Main()
{
Console.WriteLine("Hello world!");
}

这是因为编译器通常会忽略注释,除非它们是文档注释,或者您正在生成需要行号才能正常工作的调试符号。

最新更新