我只是在看一个项目,而且我看到了一些我认为不应该工作的工作。
如果您查看我在名称空间CustomFields.DateTimeField.Drivers
中的下方代码段,该文件中唯一的其他using
语句是下面的其他名称空间 {{ 1}}。
但如果您查看CustomFields.DateTimeField
行,则表明其使用的是public class DateTimeFieldDriver
类型。
查看命名空间Fields.DateTimeField
中DateTimeField
的定义,但我只为其姐妹命名空间设置了使用。
所以问题是双重的 - 为什么这有效?这被认为是一种不好的做法吗?
相关代码段:
CustomFields.DateTimeField.Fields
如果你想调查项目(MVC2项目),项目可以是downloaded here。
答案 0 :(得分:5)
当您将代码声明为特定名称空间(例如CustomFields.DateTimeField.Drivers
)时,您隐式导入所有“父”名称空间。
在这种情况下,您有CustomFields
和CustomFields.DateTimeField
的隐含使用。这就是为什么您不必为using
中的类型以及其中包含的子名称空间指定明确的CustomFields.DateTimeField
语句。
因此,通过将Fields.DateTimeField
(隐含的命名空间)与CustomFields.DateTimeField
(显式命名空间)组合以找到Fields.DateTimeField
来找到CustomFields.DateTimeField.Fields.DateTimeField
。
不,据我所知,这不是一种不好的做法。
答案 1 :(得分:3)
在C#中,当您在命名空间内时,每个父命名空间都有隐式using
。例如,在此文件中:
using System;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
与此文件相同:
using System;
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
如果您导入了名称空间,那么您不需要指定完整名称空间来访问同级名称空间树的成员,前提是它与导入的名称空间具有相同的前缀:
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
namespace Foo.Bar.Norf {
class Guf : Bar.Baz.Qux { // namespace `Foo.` is implicitly assumed to prefix the namespace reference `Bar.Baz`
}
}
\EOF
您正在体验这两种效果:对隐式导入的命名空间使用隐式名称空间前缀。
至于"不良做法" - 有经验的C#开发人员会熟悉这种细微差别,但除非你的名字含糊不清,否则通常不会有问题。
作为提示,请尽量减少命名空间及其深度的数量。例如,在您的情况下,我看到您在其自己的DateTimeField
命名空间中存储特定于DateTime的内容。这有一个糟糕的代码味道"对我来说。我会把所有内容都放在CustomFields
命名空间中,特别是因为您已经为每个类型名称指定了前缀DateTime
,所以它只是双重输入。
如果命名空间中的类型少于5种,FxCop会抱怨,顺便说一句。
更新:我看了一下C#规范(http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf),第16节,但我找不到它的任何部分,说明父命名空间是隐式导入的,这很奇怪。 / p>