这两个声明有什么区别?

时间:2022-03-30 22:27:24

Given this declaration:

鉴于此声明:

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

namespace AProject.Helpers
{
    public static class AClass
    {

and this declaration

和这个宣言

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

    public static class AClass
    {

are there any difference in any sense between them? Or is just a difference in coding styles?

他们之间有什么区别吗?或者只是编码风格的差异?

I allways used to declared my classes like the first, but recently noticed that Microsoft uses the second.

我总是习惯于像第一个一样宣布我的课程,但最近注意到微软使用了第二个。

7 个解决方案

#1


In the latter version the using directives only apply within the namespace declaration.

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

In most cases you'll only have a single namespace declaration:

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

// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}
// End of file

The main difference is if you have multiple namespaces in the same file:

主要区别在于,如果同一文件中有多个名称空间:

// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}

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

In this case the using directives in the namespace X declaration don't affect the code inside the namespace Y declaration, and vice versa.

在这种情况下,名称空间X声明中的using指令不会影响名称空间Y声明中的代码,反之亦然。

However, that's not the only difference - there's a subtle case which Eric Lippert points out where it can affect the code even with just a single namespace declaration. (Basically if you write using Foo; inside the namespace X declaration, and there's a namespace X.Foo as well as Foo, the behaviour changes. This can be remedied using a namespace alias, e.g. using global::Foo; if you really want.)

然而,这并不是唯一的区别 - 有一个微妙的案例,Eric Lippert指出即使只有一个命名空间声明它也可以影响代码。 (基本上如果你使用Foo编写;在命名空间X声明中,并且有一个名称空间X.Foo以及Foo,行为会发生变化。这可以使用命名空间别名来解决,例如使用global :: Foo;如果你真的想要。)

Personally I'd stick to:

我个人坚持:

  • One namespace declaration per file (and usually one top-level type per file)
  • 每个文件一个名称空间声明(通常每个文件一个*类型)

  • Using directives outside the namespace declaration
  • 在名称空间声明之外使用指令

#2


It makes the using directives local to that namespace, which in practice should make no difference since you're (hopefully) not declaring multiple types in multiple namespaces in a single source file.

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

Details here.

#3


The second can be ambiguous;

第二个可能是模棱两可的;

The top one makes it clear your after these namespaces:

最重要的一个是在这些命名空间之后清楚地表明你:

  • System
  • System.Collections
  • System.Collections.Generic

While the second one will first look for these namespaces:

而第二个将首先查找这些名称空间:

  • AProject.Helpers.System
  • AProject.Helpers.System.Collections
  • AProject.Helpers.System.Collections.Generic

And refer to them instead if they're found... If not, they'll both refer to the same namespaces.

如果找到它们,请参考它们......如果没有,它们都会引用相同的命名空间。

The safer rewrite of the second one would be:

第二个更安全的重写将是:

namespace AProject.Helpers
{
    using global::System;
    using global::System.Collections;
    using global::System.Collections.Generic;
}

#4


Another important difference between them arises when using LINQ-to-SQL and the generated datacontext classes. For example, the Northwind sample database; initially, you get:

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

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

If you now want to extend the partial classes by adding your own Northwind.cs, you get

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

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

Amusingly, there is a bug in the code-generator (MSLinqToSQLGenerator) - which means that if the using directives are outside the namespace (like they are by default), it breaks - with the message:

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

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

自定义工具“MSLinqToSQLGenerator”失败。未指定的错误

And the Northwind.designer.cs file gets deleted. No more data-context!

并且Northwind.designer.cs文件被删除。没有更多的数据背景!

However, if you move the using directives inside the namespace (and re-run the custom tool - right click in solution explorer), it works correctly.

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

So: this isn't a language detail - it is simply a bug in the code generator; but there is a pretty big difference between "works correctly" and the generated code getting deleted...

所以:这不是语言细节 - 它只是代码生成器中的一个错误;但是“正常工作”和生成的代码被删除之间有一个很大的区别......

Note you can also fix this simply by calling your file something different - such as NorthwindExtras.cs.

请注意,您也可以通过调用不同的文件来解决此问题 - 例如NorthwindExtras.cs。

Freaky.

#5


I guess there might be reason to use the second alternative from a purist perspective, since it makes more obviously clear what the scope of the using directives is.

我想可能有理由从纯粹主义的角度使用第二种替代方案,因为它更清楚地表明了使用指令的范围是什么。

#6


In the first example, the using declarations are "global" to the whole file. In the second example, the using statements will only apply to the code wrapped up in the namespace block.

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

I think the only time this really matters is if you have more than one namespace in the file, and want to limit which namespace has access to each using declaration.

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

#7


And for the process that Arjan points out, it's considered to be bad practice to declare usings inside your namespace. They can be implicitly overridden by another namespace.

对于Arjan指出的过程,在命名空间内声明使用是不好的做法。它们可以被另一个名称空间隐式覆盖。

#1


In the latter version the using directives only apply within the namespace declaration.

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

In most cases you'll only have a single namespace declaration:

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

// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}
// End of file

The main difference is if you have multiple namespaces in the same file:

主要区别在于,如果同一文件中有多个名称空间:

// Using directives
...
namespace X
{
    // Maybe more using directives
    // Code
}

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

In this case the using directives in the namespace X declaration don't affect the code inside the namespace Y declaration, and vice versa.

在这种情况下,名称空间X声明中的using指令不会影响名称空间Y声明中的代码,反之亦然。

However, that's not the only difference - there's a subtle case which Eric Lippert points out where it can affect the code even with just a single namespace declaration. (Basically if you write using Foo; inside the namespace X declaration, and there's a namespace X.Foo as well as Foo, the behaviour changes. This can be remedied using a namespace alias, e.g. using global::Foo; if you really want.)

然而,这并不是唯一的区别 - 有一个微妙的案例,Eric Lippert指出即使只有一个命名空间声明它也可以影响代码。 (基本上如果你使用Foo编写;在命名空间X声明中,并且有一个名称空间X.Foo以及Foo,行为会发生变化。这可以使用命名空间别名来解决,例如使用global :: Foo;如果你真的想要。)

Personally I'd stick to:

我个人坚持:

  • One namespace declaration per file (and usually one top-level type per file)
  • 每个文件一个名称空间声明(通常每个文件一个*类型)

  • Using directives outside the namespace declaration
  • 在名称空间声明之外使用指令

#2


It makes the using directives local to that namespace, which in practice should make no difference since you're (hopefully) not declaring multiple types in multiple namespaces in a single source file.

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

Details here.

#3


The second can be ambiguous;

第二个可能是模棱两可的;

The top one makes it clear your after these namespaces:

最重要的一个是在这些命名空间之后清楚地表明你:

  • System
  • System.Collections
  • System.Collections.Generic

While the second one will first look for these namespaces:

而第二个将首先查找这些名称空间:

  • AProject.Helpers.System
  • AProject.Helpers.System.Collections
  • AProject.Helpers.System.Collections.Generic

And refer to them instead if they're found... If not, they'll both refer to the same namespaces.

如果找到它们,请参考它们......如果没有,它们都会引用相同的命名空间。

The safer rewrite of the second one would be:

第二个更安全的重写将是:

namespace AProject.Helpers
{
    using global::System;
    using global::System.Collections;
    using global::System.Collections.Generic;
}

#4


Another important difference between them arises when using LINQ-to-SQL and the generated datacontext classes. For example, the Northwind sample database; initially, you get:

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

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

If you now want to extend the partial classes by adding your own Northwind.cs, you get

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

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

Amusingly, there is a bug in the code-generator (MSLinqToSQLGenerator) - which means that if the using directives are outside the namespace (like they are by default), it breaks - with the message:

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

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

自定义工具“MSLinqToSQLGenerator”失败。未指定的错误

And the Northwind.designer.cs file gets deleted. No more data-context!

并且Northwind.designer.cs文件被删除。没有更多的数据背景!

However, if you move the using directives inside the namespace (and re-run the custom tool - right click in solution explorer), it works correctly.

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

So: this isn't a language detail - it is simply a bug in the code generator; but there is a pretty big difference between "works correctly" and the generated code getting deleted...

所以:这不是语言细节 - 它只是代码生成器中的一个错误;但是“正常工作”和生成的代码被删除之间有一个很大的区别......

Note you can also fix this simply by calling your file something different - such as NorthwindExtras.cs.

请注意,您也可以通过调用不同的文件来解决此问题 - 例如NorthwindExtras.cs。

Freaky.

#5


I guess there might be reason to use the second alternative from a purist perspective, since it makes more obviously clear what the scope of the using directives is.

我想可能有理由从纯粹主义的角度使用第二种替代方案,因为它更清楚地表明了使用指令的范围是什么。

#6


In the first example, the using declarations are "global" to the whole file. In the second example, the using statements will only apply to the code wrapped up in the namespace block.

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

I think the only time this really matters is if you have more than one namespace in the file, and want to limit which namespace has access to each using declaration.

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

#7


And for the process that Arjan points out, it's considered to be bad practice to declare usings inside your namespace. They can be implicitly overridden by another namespace.

对于Arjan指出的过程,在命名空间内声明使用是不好的做法。它们可以被另一个名称空间隐式覆盖。