我一直在一些C#代码上运行StyleCop,它不断报告我的using指令应该在命名空间中。
是否有技术原因将using指令放在命名空间内部而不是外部?
我一直在一些C#代码上运行StyleCop,它不断报告我的using指令应该在命名空间中。
是否有技术原因将using指令放在命名空间内部而不是外部?
当前回答
正如杰佩·斯蒂格·尼尔森(Jeppe Stig Nielsen)所说,这条线索已经有了很好的答案,但我认为这一相当明显的微妙之处也值得一提。
使用在名称空间中指定的指令可以缩短代码,因为它们不需要像在外部指定时那样完全限定。
以下示例之所以有效,是因为类型Foo和Bar都位于同一个全局命名空间Outer中。
假设代码文件Foo.cs:
namespace Outer.Inner
{
class Foo { }
}
和Bar.cs:
namespace Outer
{
using Outer.Inner;
class Bar
{
public Foo foo;
}
}
这可能会省略using指令中的外部命名空间,简称:
namespace Outer
{
using Inner;
class Bar
{
public Foo foo;
}
}
其他回答
尚未提及:
将using指令放在命名空间声明中是众所周知的最佳编程实践的一个应用,即在尽可能小的范围内声明所有内容。
如果最佳编程实践是您的第二天性,那么您可以自动执行类似的操作。
这可能是将using指令放在命名空间声明中的最佳理由,而不管其他地方提到的(边界)技术(边界)优点;就这么简单。
已经提到了,但可能更好地说明了:
在名称空间中放置using指令可以避免不必要的重复,并使声明更加简洁。
这是不必要的简洁:
using Com.Acme.Products.Traps.RoadRunnerTraps;
namespace Com.Acme.Products.Traps {
这是甜蜜的,切中要害:
namespace Com.Acme.Products.Traps {
using RoadRunnerTraps;
当您希望使用别名时,在名称空间中放置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>>>;
不漂亮。
将其放在名称空间中会使声明成为文件的该名称空间的本地声明(如果文件中有多个名称空间),但如果每个文件只有一个名称空间,那么它们在名称空间外部还是内部都没有太大区别。
using ThisNamespace.IsImported.InAllNamespaces.Here;
namespace Namespace1
{
using ThisNamespace.IsImported.InNamespace1.AndNamespace2;
namespace Namespace2
{
using ThisNamespace.IsImported.InJustNamespace2;
}
}
namespace Namespace3
{
using ThisNamespace.IsImported.InJustNamespace3;
}
答案中讨论了技术原因,我认为这最终取决于个人偏好,因为差异没有那么大,而且两者都存在权衡。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"
}
}
}
您可以在解决方案级别创建此配置文件,并将其作为“现有链接文件”添加到项目中,以便在所有项目中共享配置。
如果源解决方案中使用的默认引用(即“引用”)应该在命名空间之外,而那些“新添加的引用”是一个很好的做法,则应将其放在命名空间内。这是为了区分要添加的引用。