.net 4.0-C#4是否以以前的C#版本没有的方式优化了名称空间?

这个问题是出于兴趣。 我正在使用第三方库,并且在CMS.Security.Dummy类上遇到了以下文档:

不要删除该类-此类阻止编译器执行以下操作: 在.NET 4.0下删除整个命名空间。

是否有人知道或有人推测如果删除了伪类,.NET 4为什么会删除命名空间?

由于.NET 4是在源代码注释中显式命名的,因此我假定以前的C#版本表现出不需要此伪类的行为。 不过,这纯粹是猜测。

屏幕截图

documentation

反编译的源代码

#region Assembly CMS.SettingsProvider.dll, v4.0.30319
// ...\solution\wwwroot\Bin\CMS.SettingsProvider.dll
#endregion

using System;

namespace CMS.Security
{
    // Summary:
    //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
    //     entire namespace under .NET 4.0.
    public class Dummy
    {
        // Summary:
        //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
        //     entire namespace under .NET 4.0.
        public Dummy();
    }
}
John K asked 2020-07-01T19:36:13Z
3个解决方案
90 votes

一个鲜为人知的事实是,从底层CLR类型系统的角度来看,没有“命名空间”之类的东西。 相反,这只是一个约定,我们说名称中包含句点的类型是“名称空间的成员”。 逻辑上,法律代码之间没有任何区别:

namespace N
{
    class C  {}
}

和伪代码:

class N.C {}

C#强迫您假装这种令人愉悦的小说是现实,但这只是一种小说-当然,从CLR类型系统的角度来看。 从C#编译器的角度来看,名称空间当然是“真实的”。 除了类型名称的一部分之外,它们仅与元数据中的任何其他内容都不对应。

简而言之:如果您使用“空”名称空间创建程序集,则在已编译的二进制文件中根本不存在“名称空间”。 仅当库中存在名称中带有句点的类型时,“名称空间”才存在。

现在,为什么您要关心确保“空”名称空间以二进制形式存在,我不知道。

我假设以前的C#版本表现出不需要此伪类的行为

不。 自1.0以来的每个C#版本都会丢弃空的名称空间。

Eric Lippert answered 2020-07-01T19:36:54Z
23 votes

考虑到命名空间不包含任何成员(没有该类),我不确定在那个时候甚至没有命名空间的概念……我也不希望它有用。

我刚刚尝试使用C#2编译器重现此代码,但在IL中看不到任何有关空名称空间的痕迹。

Jon Skeet answered 2020-07-01T19:37:19Z
7 votes

我能想到的唯一半相关的问题是,在msbuild中编译项目时,间接引用并不总是复制到当前应用程序的bin目录中。 如果库B间接引用了库A,而库C仅引用了B,则在编译库C时库A的输出不一定会复制到bin文件夹中。过去,我在类上使用了空字段引用来确保 依赖关系是显式的,并且输出已正确部署。 也许原始的开发人员经历过类似的事情,这就是他们的解决方案?

Chris answered 2020-07-01T19:37:39Z
translate from https://stackoverflow.com:/questions/9574420/does-c-sharp-4-optimize-away-namespaces-in-a-manner-that-previous-c-sharp-versio