C#4是否以先前的C#版本没有的方式优化名称空间?

Joh*_*n K 45 c# namespaces .net-4.0

这个问题是为了感兴趣.我正在使用第三方库,并在CMS.Security.Dummy类中遇到以下文档:

不要删除此类 - 此类可防止编译器在.NET 4.0下删除整个命名空间.

有人知道,或者任何人都可以推测为什么.NET 4会在删除虚拟类时删除命名空间?

因为.NET 4在源代码注释中明确命名,所以我假设以前的C#版本表现出不需要这个虚拟类的行为.这纯粹是推测性的.

屏幕截图

文件

反编译源代码

#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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 90

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

namespace N
{
    class C  {}
}
Run Code Online (Sandbox Code Playgroud)

和伪代码:

class N.C {}
Run Code Online (Sandbox Code Playgroud)

C#迫使你假装这个令人愉快的小说是现实,但它只是一个虚构 - 当然,从CLR类型系统的角度来看.从C#编译器的角度来看,名称空间当然是"真实的".除了类型名称的一部分之外,它们只对应于元数据中的任何内容.

简而言之:如果使用"空"命名空间创建程序集,则编译后的二进制文件中根本不存在"命名空间".只有当库中存在名称中包含句点的类型时,才会出现"名称空间".

现在,为什么你会关心确保"空"命名空间以二进制形式存在,我不知道.

我假设以前的C#版本表现出不需要这个虚拟类的行为

不.从1.0开始,每个版本的C#都会抛弃空命名空间.

  • 很棒的答案/解释! (2认同)
  • 我认为他们关心空命名空间的原因是因为他们在其他地方的 using 语句中引用了它。如果命名空间不存在,则 using 语句将出现编译时错误。为什么不直接删除 using 语句呢?它可能是他们无法控制的某些代码生成工具的输出。(至少,这是我以前遇到过的情况。) (2认同)

Jon*_*eet 23

鉴于命名空间不包含任何成员(没有该类),我不确定在那时甚至还有命名空间的概念 ......我也不希望它有用.

我刚刚尝试使用C#2编译器重现这一点,我在IL中看不到任何空命名空间的痕迹.


Chr*_*ris 7

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