这两个声明有什么区别?

9

给定以下声明:

using System;
using System.Collections;
using System.Collections.Generic;

namespace AProject.Helpers
{
    public static class AClass
    {

并且这个声明

namespace AProject.Helpers
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public static class AClass
    {

它们在任何意义上有区别吗?还是只是编码风格的不同?

我一直习惯于像第一个那样声明我的类,但最近注意到微软使用了第二种方式


1
看起来是一个重复的问题。请参考“应该将Usings放在命名空间内还是外部”的优秀答案。 - tsemer
7个回答

26
在后面的版本中,使用指令只适用于命名空间声明内部。
在大多数情况下,您只会有一个命名空间声明。
// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}
// End of file

主要区别在于,如果您在同一文件中有多个命名空间:
// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}

namespace Y
{
    // Maybe more using directives
    // Code
}
// End of file

在这种情况下,名称空间X声明中的using指令不会影响名称空间Y声明内的代码,反之亦然。
然而,这不是唯一的区别 - Eric Lippert指出了一个微妙的情况,即使只有单个名称空间声明,它也会影响代码。(基本上,如果你在名称空间X声明内写入using Foo;,并且存在名称空间X.FooFoo,行为将发生变化。如果你真的想要解决这个问题,可以使用名称空间别名,例如using global::Foo;。)
就我个人而言,我会坚持以下做法:
  • 每个文件一个名称空间声明(通常每个文件一个顶层类型)
  • 在名称空间声明外使用using指令

6

它使使用指令局限于该命名空间,实际上应该没有区别,因为您(希望)不会在单个源文件中声明多个类型和多个命名空间。

详情请参见此处


这可能会在边缘情况下产生影响。请查看我的回答中的链接。 - Jon Skeet

2
第二个有歧义;
第一个明确了你要使用以下这些命名空间:
- System - System.Collections - System.Collections.Generic
而第二个会首先查找以下这些命名空间:
- AProject.Helpers.System - AProject.Helpers.System.Collections - AProject.Helpers.System.Collections.Generic
如果找到了,就会使用它们...如果没有找到,则它们都将引用相同的命名空间。
第二个更安全的重写方式是:
namespace AProject.Helpers
{
    using global::System;
    using global::System.Collections;
    using global::System.Collections.Generic;
}

1

使用LINQ-to-SQL和生成的数据上下文类时,它们之间的另一个重要区别在于。例如,Northwind示例数据库;最初,您会得到:

  • Northwind.dbml
    • Northwind.dbml.layout
    • Northwind.designer.cs

如果您现在想通过添加您自己的Northwind.cs来扩展部分类,则会获得

  • Northwind.dbml
    • Northwind.dbml.layout
    • Northwind.designer.cs
    • Northwind.cs

有趣的是,在代码生成器(MSLinqToSQLGenerator)中存在一个错误 - 这意味着如果 using 指令命名空间之外(就像默认情况下一样),它会出错,并显示以下消息:

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

然后,Northwind.designer.cs 文件将被删除。没有数据上下文了!

但是,如果您将 using 指令放在命名空间内(并重新运行自定义工具 - 在解决方案资源管理器中右键单击),它将正常工作。

因此:这不是语言细节 - 它只是代码生成器中的一个错误;但是“正常工作”和生成的代码被删除之间存在相当大的差异...

请注意,您还可以通过将文件命名为其他名称(例如 NorthwindExtras.cs)来轻松解决此问题。

奇怪。


0

从纯粹主义的角度来看,使用第二种替代方案可能有理由,因为它更明显地表明了 using 指令作用域的范围。


0
在第一个示例中,using声明是整个文件的“全局”声明。在第二个示例中,using语句仅适用于封装在命名空间块中的代码。
我认为这真正有意义的唯一时候是,如果您在文件中有多个命名空间,并且想要限制每个using声明可以访问哪个命名空间。

0

至于Arjan指出的过程,将using声明放在命名空间内被认为是不好的实践。它们可能会被另一个命名空间隐式覆盖。


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