为什么这个名称空间正确解析?

时间:2014-11-14 02:06:11

标签: c#

我只是在看一个项目,而且我看到了一些我认为不应该工作的工作。

如果您查看我在名称空间CustomFields.DateTimeField.Drivers中的下方代码段,该文件中唯一的其他using语句是下面的其他名称空间 {{ 1}}。

但如果您查看CustomFields.DateTimeField行,则表明其使用的是public class DateTimeFieldDriver类型。

查看命名空间Fields.DateTimeFieldDateTimeField的定义,但我只为其姐妹命名空间设置了使用。

所以问题是双重的 - 为什么这有效?这被认为是一种不好的做法吗?

相关代码段:

CustomFields.DateTimeField.Fields

如果你想调查项目(MVC2项目),项目可以是downloaded here

2 个答案:

答案 0 :(得分:5)

当您将代码声明为特定名称空间(例如CustomFields.DateTimeField.Drivers)时,您隐式导入所有“父”名称空间。

在这种情况下,您有CustomFieldsCustomFields.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>