【问题标题】:C# using namespace directive in nested namespacesC# 在嵌套命名空间中使用命名空间指令
【发布时间】:2011-01-02 20:16:24
【问题描述】:

对,我通常使用如下的“使用”指令

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AwesomeLib
{
  //awesome award winning class declarations making use of Linq
}

我最近看到了这样的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AwesomeLib
{
  //awesome award winning class declarations making use of Linq

  namespace DataLibrary
  {
    using System.Data;

    //Data access layers and whatnot
  }

}

当然,我知道我可以将 USING 放在我的命名空间声明中。如果你的命名空间在同一个根目录下(它们是有组织的),这样的事情对我来说是有意义的。

System;
namespace 1 {}
namespace 2 
{
  System.data;
}

但是嵌套命名空间呢?就个人而言,我会将所有 USING 声明留在您可以轻松找到它们的顶部。相反,它们似乎遍布整个源文件。

在嵌套命名空间中以这种方式使用 USING 指令有什么好处?比如内存管理还是 JIT 编译器?

【问题讨论】:

  • 我认为微软编码指南告诉你将 usings 放在命名空间范围内,stylecop 总是对此抱怨。我个人更喜欢将它们放在文件的顶部。

标签: c# namespaces using-directives


【解决方案1】:

IL 代码不反映 C# using

运行时性能

USING 有什么好处吗 以这种方式使用的指令 嵌套命名空间? 如内存 管理还是 JIT 编译器?

因为您是在询问运行时性能,所以我们来看看源代码下面发生了什么。

如果您使用Microsoft's IL Diassembler tool(正如我们在这里所做的那样)查看编译后的 IL 代码,您将看到无论程序员如何在源代码中使用 using,所有类名始终都是完全限定的。

以下编译的 IL 代码示例中,请注意没有看到“快捷方式”机制,尽管 using 在原始 C# 源代码文件中。例如,IL 描述了一个很长的 extends [System.Web]System.Web.UI.Page,而 C# 会使用 : Pageusing System.Web.UI;(两个单独的语句)。

// ***** Compiled MSIL CODE ****
// Notice all fully qualified classes throughout.
// 

.class public auto ansi beforefieldinit WebApplication1.process
       extends [System.Web]System.Web.UI.Page
{
  .field family class [System.Web]System.Web.UI.HtmlControls.HtmlForm form1
  .method family hidebysig instance void 
          Page_Load(object sender,
                    class [mscorlib]System.EventArgs e) cil managed
  {
    // Code size       95 (0x5f)
    .maxstack  4
    .locals init ([0] string strName,
             [1] string strTime)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  call       instance class [System.Web]System.Web.HttpRequest [System.Web]System.Web.UI.Page::get_Request()
    IL_0007:  ldstr      "name"
    IL_000c:  callvirt   instance string [System.Web]System.Web.HttpRequest::get_Item(string)

在编译后的 IL 中,所有类都是完全限定的。

这意味着根据设计时using 语句,在运行时没有性能优势或劣势。

编译时间

根据您在源代码中分散usings 和namespaces 的方式,可能会有更多或更少的关键字。编译器必须看到它们并处理它们,但与编译器必须做的所有事情相比,编译性能对于这样微不足道的事情来说是可以忽略不计的。

设计时间优势

命名空间是一种组织技术,using 是一种在源代码级别管理它们的方法(并指示编译器如何使用它们,以便它可以相应地编译程序)。当 C# 源代码指定using System.Web.UI; 时,不会导入任何内容且文件大小不会变大(因为已在其中引用了程序集);相反,using 只是在使用 using 的范围内对该命名空间的内容产生更短的语法,无论是在整个文件范围内还是在内部声明的命名空间范围内文件。

如果使用得当,程序员的好处是可以减少多个命名空间usings 之间的模棱两可的类名冲突。

源代码命名空间的组织在编译的 IL 代码中以不同的方式表示(如上例所示)。

【讨论】:

    【解决方案2】:

    生成的中间语言没有任何好处。由于 CIL 是 JIT 编译器的输入,因此也不受影响。

    既然您在谈论最佳实践:最佳实践是每个文件只有一个类,因此您也只有一个命名空间。

    【讨论】:

      【解决方案3】:

      来自Style Cop rules

      1. 在命名空间中放置 using-alias 指令可消除冲突类型之间的编译器混淆。
      2. 当在一个文件中定义了多个命名空间时,在命名空间元素中放置 using 指令会影响引用和别名。

      【讨论】:

        【解决方案4】:

        using 子句仅有助于使您的代码更易于维护,它们不会影响代码 AFAIK 的性能。

        这同样适用于命名空间 - 您可以将所有类放在全局命名空间中并将它们命名为 Class1、Class2 等,您的代码也会执行同样的操作。但这将是一场噩梦!

        所以他们都在那里帮助你,编码员,他们不会影响编译的代码。

        【讨论】:

          【解决方案5】:

          当您处于不需要 System.Data 的范围内时,最好不要让 IntelliSense 触发 System.Data 成员来处理您正在寻找的其他事情

          关于一些性能问题 - 我认为您喜欢如何使用它并不重要...

          【讨论】:

            猜你喜欢
            • 2019-08-03
            • 2020-05-20
            • 1970-01-01
            • 2011-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-06
            • 1970-01-01
            相关资源
            最近更新 更多