为了账号安全,请及时绑定邮箱和手机立即绑定

“使用”指令应该在名称空间内还是在名称空间之外?

“使用”指令应该在名称空间内还是在名称空间之外?

忽然笑 2019-06-09 15:39:00
“使用”指令应该在名称空间内还是在名称空间之外?我一直在跑步StyleCop在一些C#代码上,它不断地报告说,我的using指令应该在命名空间中。是否有技术原因将using在名称空间内而不是在名称空间之外的指令?
查看完整描述

3 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

这个线程已经有了一些很好的答案,但是我觉得我可以用这个额外的答案带来更多的细节。

首先,请记住带有句点的命名空间声明,如:

namespace MyCorp.TheProduct.SomeModule.Utilities{
    ...}

完全等同于:

namespace MyCorp{
    namespace TheProduct
    {
        namespace SomeModule
        {
            namespace Utilities
            {
                ...
            }
        }
    }}

如果你想,你可以using所有这些级别的指令。(当然,我们希望usingIt‘只在一个地方,但根据语言,这是合法的。)

解析隐含的类型的规则可以松散地表述如下:首先搜索内部最“范围”以进行匹配,如果没有发现,则从一个级别到下一个范围进行搜索,以此类推。直到找到匹配为止。如果在某个级别找到多个匹配,如果其中一个类型来自当前程序集,则选择该类型并发出编译器警告。否则,放弃(编译时错误)。

现在,让我们在两个主要约定的具体示例中明确说明这意味着什么。

(1)外部使用:

using System;using System.Collections.Generic;using System.Linq;//using MyCorp.TheProduct;  <-- uncommenting this would change nothingusing 
MyCorp.TheProduct.OtherModule;using MyCorp.TheProduct.OtherModule.Integration;using ThirdParty;namespace MyCorp.TheProduct.SomeModule
.Utilities{
    class C    {
        Ambiguous a;
    }}

在上述情况下,找出哪种类型Ambiguous是,搜索按以下顺序进行:

  1. 嵌套类型

    C

    (包括继承的嵌套类型)
  2. 当前命名空间中的类型

    MyCorp.TheProduct.SomeModule.Utilities

  3. 命名空间中的类型

    MyCorp.TheProduct.SomeModule

  4. 类型

    MyCorp.TheProduct

  5. 类型

    MyCorp

  6. 类中的类型。

    命名空间(全局命名空间)
  7. 类型

    SystemSystem.Collections.GenericSystem.LinqMyCorp.TheProduct.OtherModuleMyCorp.TheProduct.OtherModule.Integration

    ,和

    ThirdParty

另一项公约:

(2)内部使用:

namespace MyCorp.TheProduct.SomeModule.Utilities{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using MyCorp.TheProduct;                           // MyCorp can be left out; this using is NOT redundant
    using MyCorp.TheProduct.OtherModule;               // MyCorp.TheProduct can be left out
    using MyCorp.TheProduct.OtherModule.Integration;   // MyCorp.TheProduct can be left out
    using ThirdParty;

    class C    {
        Ambiguous a;
    }}

现在,搜索类型Ambiguous按以下顺序排列:

  1. 嵌套类型

    C

    (包括继承的嵌套类型)
  2. 当前命名空间中的类型

    MyCorp.TheProduct.SomeModule.Utilities

  3. 类型

    SystemSystem.Collections.GenericSystem.LinqMyCorp.TheProductMyCorp.TheProduct.OtherModuleMyCorp.TheProduct.OtherModule.Integration

    ,和

    ThirdParty

  4. 命名空间中的类型

    MyCorp.TheProduct.SomeModule

  5. 类型

    MyCorp

  6. 类中的类型。

    命名空间(全局命名空间)

(请注意,MyCorp.TheProduct是“3”的一部分因此在“4”之间不需要。及“5.”)

结束语

无论您在名称空间声明中还是在名称空间声明之外,都有可能会有人稍后向具有较高优先级的名称空间中的一个添加具有相同名称的新类型。

此外,如果嵌套命名空间的名称与类型相同,则可能会导致问题。

将用户从一个位置移动到另一个位置总是很危险的,因为搜索层次结构会发生变化,并且可能会找到另一种类型。因此,选择一个惯例,并坚持它,这样你就不会再移动使用。

默认情况下,VisualStudio的模板将使用名称空间(例如,如果使VS在新文件中生成一个新类)。

有用法的一个(微小的)优势然后,您可以为全局属性使用指令,例如[assembly: ComVisible(false)]而不是[assembly: System.Runtime.InteropServices.ComVisible(false)].


查看完整回答
反对 回复 2019-06-09
  • 3 回答
  • 0 关注
  • 390 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信