C# - using语句的位置

10

在C#代码文件中,使用语句应该放在最外层作用域还是放在命名空间内部这个问题一直存在争议。我知道使用语句的位置会影响文件中引用的范围,但我不明白为什么在大多数情况下,有人会想要把使用语句放在命名空间内部。

几乎所有情况下,单个文件中只存在一个命名空间声明,因此对使用语句进行作用域限定似乎是没有意义的。如果将多个类型和多个命名空间放在同一个文件中,则作用域限定的使用语句很有意义,但即使在只有一个命名空间的文件中,我仍然看到有很多这样的情况。为什么呢?

using System;

namespace MyNamespace
{
    using System.Text;

    public class MyClass {
        // ...
    }
}

看起来毫无必要地在整个项目中都这样做的一个例子是ASP.NET MVC源代码


2
这个问题已经被反复讨论过了。其中的“为什么”在这篇文章中有详细解释:https://dev59.com/L3VC5IYBdhLWcg3w-mdO - womp
你的“搜索术”比我高明…当我搜索类似内容时,我没能找到那篇帖子。 :) - Nathan Taylor
只是为了澄清,这个问题实际上是关于using Directive而不是using Statement - mwardm
3个回答

13

"using"语句放在文件顶部是Visual Studio的默认方式。然而,推荐的方法是将"using"语句放置在命名空间内部。即使是微软的StyleCop也会捕捉到这一点,并表示VS的默认方式是错误的。

这两种技术都可以正常工作。

StyleCop规则说: 将多个命名空间元素放在单个文件中通常不是一个好主意,但如果确实需要这样做,最好将每个命名空间元素内的所有使用指令放置其中,而不是全局地放在文件顶部。这将紧密限定命名空间的范围,还有助于避免上面所述的问题。

值得注意的是,当代码的using指令放在命名空间之外时,移动这些指令到命名空间内部时应该小心,以确保不会改变代码的语义。正如上面所解释的,将using别名指令放在命名空间元素中允许编译器以一种不会在指令放在命名空间之外时出现的方式在冲突类型之间进行选择。

以下是一些进一步了解的链接:

  • sa1200:using指令必须放置在命名空间内

  • 6
    抱歉,这个说法是错误的。首先,using指令不引用_程序集_,而是导入_命名空间_!例如,namespace System 存在于 mscorlib.dllSystem.dllSystem.Core.dll 程序集中。此外,C# 的 using 指令对输出的 MSIL 没有任何影响,因为 MSIL 总是使用完整的类型名称,并没有"命名空间"的概念。Scott 文章中观察到的效果很可能与_VS调试器_在具有源代码时如何处理装载程序集有关。 - Pavel Minaev
    4
    啊,实际上,现在我仔细阅读了斯科特的博客文章后,他实际上是在揭穿这种说法。具体来说,他说:“如果我在命名空间内使用相同的 usings,我会得到相同的结果……我99.99%确定在这一点上,using 指令不能改变您的程序集加载行为,而且我认为我怀疑是正确的。” - Pavel Minaev
    1
    糟糕,引号错误了。已更新。 - Jim W
    @Jim W,你引用了Scott的话出错了。他在证明别人错误之前引用了别人的话。 - grenade
    但是,为什么这是推荐的方法? - Lucas
    1
    将using-alias指令放置在命名空间元素内部,允许编译器以在指令放置在命名空间之外时不会发生的方式在冲突类型之间进行选择。 - Jim W

    3

    在开始使用 StyleCop 并被 规则 SA1200 拦截之前,我从未听说过这种做法。很奇怪的是,Visual Studio 在创建新项目时生成的 .cs 文件违反了此规则,将 using 指令放置在命名空间之外的文件开头。


    0

    修改,我感到惭愧

    啊!你提到的using语句是用于导入命名空间,而不是包装一个IDisposable对象!

    非常不同、模糊的术语……你让我困惑了 :-)

    个人喜欢将它们放在文件顶部的命名空间外面;但这可能是因为我在C#和VB.NET之间切换。

    我喜欢将我的项目组织成每个类一个文件,没有内部(嵌套)类,每个命名空间只有一个类(每个文件)。在这种情况下,using语句的位置无论是在命名空间内部还是外部都是无关紧要的。


    iDesign C#编码标准是一个可靠的标准,可以遵循(或从中派生自己的标准)。它建议将using语句放在命名空间之外作为第14项。但这完全取决于您公司/项目的惯例。


    那不是他所指的。 - womp
    4
    "只允许每个命名空间有一个类" - 真的吗? - grenade
    @grenade:是的,那是个笔误...本意应该是多余的,但应该是“每个命名空间每个文件一个类”。哎呀! - STW

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接