我一直在一些C#代码上运行StyleCop,它不断报告我的using指令应该在命名空间中。
是否有技术原因将using指令放在命名空间内部而不是外部?
我一直在一些C#代码上运行StyleCop,它不断报告我的using指令应该在命名空间中。
是否有技术原因将using指令放在命名空间内部而不是外部?
当前回答
根据Hanselman-使用指令和装配加载。。。和其他此类物品在技术上没有区别。
我的偏好是将它们放在名称空间之外。
其他回答
当您希望使用别名时,在名称空间中放置using语句存在问题。别名不能从前面的using语句中受益,必须完全限定。
考虑:
namespace MyNamespace
{
using System;
using MyAlias = System.DateTime;
class MyClass
{
}
}
对比:
using System;
namespace MyNamespace
{
using MyAlias = DateTime;
class MyClass
{
}
}
如果您有一个冗长的别名,如以下(这就是我发现问题的原因),这可能会特别明显:
using MyAlias = Tuple<Expression<Func<DateTime, object>>, Expression<Func<TimeSpan, object>>>;
在命名空间中使用语句时,它突然变成:
using MyAlias = System.Tuple<System.Linq.Expressions.Expression<System.Func<System.DateTime, object>>, System.Linq.Expressions.Expression<System.Func<System.TimeSpan, object>>>;
不漂亮。
答案中讨论了技术原因,我认为这最终取决于个人偏好,因为差异没有那么大,而且两者都存在权衡。Visual Studio用于创建.cs文件的默认模板使用命名空间之外的指令,例如。
通过在项目文件的根目录中添加stylecop.json文件,可以调整stylecop以使用命名空间之外的指令进行检查,如下所示:
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"orderingRules": {
"usingDirectivesPlacement": "outsideNamespace"
}
}
}
您可以在解决方案级别创建此配置文件,并将其作为“现有链接文件”添加到项目中,以便在所有项目中共享配置。
另一个我认为没有被其他答案涵盖的微妙之处是,当你有一个同名的类和命名空间时。
当您在名称空间中导入时,它将找到该类。如果导入在命名空间之外,那么将忽略导入,并且类和命名空间必须完全限定。
//file1.cs
namespace Foo
{
class Foo
{
}
}
//file2.cs
namespace ConsoleApp3
{
using Foo;
class Program
{
static void Main(string[] args)
{
//This will allow you to use the class
Foo test = new Foo();
}
}
}
//file3.cs
using Foo; //Unused and redundant
namespace Bar
{
class Bar
{
Bar()
{
Foo.Foo test = new Foo.Foo();
Foo test = new Foo(); //will give you an error that a namespace is being used like a class.
}
}
}
如果源解决方案中使用的默认引用(即“引用”)应该在命名空间之外,而那些“新添加的引用”是一个很好的做法,则应将其放在命名空间内。这是为了区分要添加的引用。
通常,外部using指令(例如System和Microsoft命名空间)应该放在命名空间指令之外。除非另有规定,否则应在所有情况下应用默认值。这应该包括不属于当前项目的任何组织内部库,或者使用引用同一项目中其他主名称空间的指令。引用当前项目和命名空间中其他模块的任何using指令都应放在命名空间指令中。这有两个特定的功能:
它提供了本地模块和“其他”模块之间的视觉区别,这意味着所有其他模块。它将本地指令的范围限定为优先于全局指令应用。
后一个原因很重要。这意味着很难引入一个不明确的引用问题,而这个引用问题可能是由一个比重构代码更重要的更改引起的。也就是说,你将一个方法从一个文件移动到另一个文件,突然出现了一个以前不存在的bug。通俗地说,一个“海森堡”——历史上极难追踪。