2009-06-05 137 views
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 
    { 

在那里它们之间任何的意义有什么区别?或者只是编码风格的差异?

我总是用来声明我的类像第一个,但最近注意到微软uses the second

+1

似乎是一个重复的问题。请参阅出色答卷 “[应Usings是命名空间内部或外部] [1]” [1]:http://stackoverflow.com/questions/125319/should-usings-be-inside-或在名称空间外 – tsemer 2012-08-03 06:53:12

回答

26

在后一版本中,using指令仅适用于名称空间声明内。

在大多数情况下,你只能有一个名称空间声明:

// 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声明中的指令不会影响名称空间Y声明内的代码,反之亦然。

但是,这不是唯一的区别 - 有一个subtle case which Eric Lippert points out即使仅使用一个名称空间声明,也可以影响代码。 (基本上,如果您在名称空间X声明中写入using Foo;,并且存在名称空间X.Foo以及Foo,则行为会发生变化。可以使用名称空间别名来补救此问题,例如using global::Foo;(如果您确实需要)。)

个人而言,我会坚持到:每个文件

  • 一个命名空间声明(和每个文件通常一个顶级型)
  • 使用空间声明之外的指令
+0

像往常一样好的答案乔恩。 +1 – 2009-07-02 13:08:41

6

它使该命名空间的本地使用指令,实际上应该没有什么区别,因为你(希望)不是在单个源文件的多个命名空间中声明多个类型。

详情here

+0

它可以在边缘情况下有所作为。请参阅我答案中的链接。 – 2009-06-05 06:24:09

0

我想可能有理由使用第二个选择从纯粹的角度来看,因为它更清楚地表明using指令的范围是什么。

0

在第一个示例中,使用声明对整个文件是“全局”的。在第二个例子中,using语句只适用于命名空间块中包装的代码。

我认为唯一真正重要的是如果文件中有多个命名空间,并且想限制哪个命名空间可以访问每个使用声明。

2

的第二可以是模棱两可的;

顶一个清楚你的这些命名空间之后:

  • 系统
  • 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; 
} 
0

而对于阿尔扬指出的过程中,它被认为是不好的做法,声明你的命名空间中usings。它们可以被另一个命名空间隐式覆盖。

1

另一个重要它们之间的区别出现在使用LINQ-to-SQL和生成的datacontext类时。例如,罗斯文示例数据库;最初,你会得到:

  • 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

怪异。