C# 为什么这个名称空间解析正确?
我只是在看一个项目,我看到一些工作,我认为不应该工作 如果您查看下面的代码段,我位于名称空间CustomFields.DateTimeField.Drivers中,该文件中唯一使用的其他语句是CustomFields.DateTimeField下面的其他名称空间 但是,如果您查看公共类DateTimeFieldDriver行,它使用的是类型Fields.DateTimeField 查看名称空间CustomFields.DateTimeField.Fields中DateTimeField的定义,但我只为其姐妹名称空间设置了usings 因此,问题有两个方面——为什么这样做有效?这被认为是一种不好的做法吗 有问题的片段:C# 为什么这个名称空间解析正确?,c#,C#,我只是在看一个项目,我看到一些工作,我认为不应该工作 如果您查看下面的代码段,我位于名称空间CustomFields.DateTimeField.Drivers中,该文件中唯一使用的其他语句是CustomFields.DateTimeField下面的其他名称空间 但是,如果您查看公共类DateTimeFieldDriver行,它使用的是类型Fields.DateTimeField 查看名称空间CustomFields.DateTimeField.Fields中DateTimeField的定义,但
using System;
using JetBrains.Annotations;
using Orchard;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Localization;
using CustomFields.DateTimeField.Settings;
using CustomFields.DateTimeField.ViewModels;
namespace CustomFields.DateTimeField.Drivers {
[UsedImplicitly]
public class DateTimeFieldDriver : ContentFieldDriver<Fields.DateTimeField> {
public IOrchardServices Services { get; set; }
private const string TemplateName = "Fields/Custom.DateTime"; // EditorTemplates/Fields/Custom.DateTime.cshtml
public DateTimeFieldDriver(IOrchardServices services) {
Services = services;
T = NullLocalizer.Instance;
}
如果您想调查MVC2项目,则可以将该项目设置为MVC2项目。当您将代码声明为位于特定名称空间(例如CustomFields.DateTimeField.Drivers)内时,您还隐式导入了所有父名称空间 在本例中,您对CustomFields和CustomFields.DateTimeField有一个隐含的用法。这就是为什么不必为CustomFields.DateTimeField中的类型以及其中包含的子名称空间指定显式using语句的原因 因此,Fields.DateTimeField是通过将CustomFields.DateTimeField(隐含名称空间)与Fields.DateTimeField(显式名称空间)相结合来找到的,以解析为CustomFields.DateTimeField.Fields.DateTimeField
不,据我所知,这并不是不好的做法。当您声明代码位于特定名称空间内时,例如CustomFields.DateTimeField.Drivers,您也隐式导入了所有父名称空间 在本例中,您对CustomFields和CustomFields.DateTimeField有一个隐含的用法。这就是为什么不必为CustomFields.DateTimeField中的类型以及其中包含的子名称空间指定显式using语句的原因 因此,Fields.DateTimeField是通过将CustomFields.DateTimeField(隐含名称空间)与Fields.DateTimeField(显式名称空间)相结合来找到的,以解析为CustomFields.DateTimeField.Fields.DateTimeField
不,据我所知,这并不是不好的做法。在C语言中,当您在一个名称空间中时,您对每个父名称空间都有隐式使用。例如,在此文件中:
using System;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
using System;
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
与此文件相同:
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命名空间中。这对我来说是一种糟糕的代码味道。我会将所有内容都放在CustomFields名称空间中,特别是因为您已经为每个typename指定了前缀DateTime,所以它只是双重键入
顺便说一句,如果命名空间中的类型少于5个,FxCop也会抱怨
更新:我查看了C规范第16节,但我找不到其中任何一部分说明父命名空间是隐式导入的,这很奇怪。在C中,当您在一个命名空间内时,您对每个父命名空间都有隐式使用。例如,在此文件中:
using System;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
using System;
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
与此文件相同:
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命名空间中。这对我来说是一种糟糕的代码味道。我会将所有内容都放在CustomFields名称空间中,特别是因为您已经为每个typename指定了前缀DateTime,所以它只是双重键入
顺便说一句,如果命名空间中的类型少于5个,FxCop也会抱怨
更新:我查看了C规范第16节,但我找不到其中任何一部分说明父名称空间是隐式导入的,这很奇怪。也许你应该检查一下MSDN对此有何评论?我想应该使用某种级联搜索来解析名称空间。我不会说这是个坏习惯,但是
拥有一个与父名称空间DateTimeField同名的类,在家中尝试肯定不是很好/安全。也许你应该检查一下MSDN对这个主题有何评论?我想应该使用某种级联搜索来解析名称空间。我不会说这是一种不好的做法,但是拥有一个与父名称空间DateTimeField同名的类肯定算不上好/安全,不适合在家中尝试。