【问题标题】:Why does being in a C# namespace hide other namespaces that start with an intermediate element of the namespace name?为什么在 C# 命名空间中会隐藏以命名空间名称的中间元素开头的其他命名空间?
【发布时间】:2021-11-10 01:13:57
【问题描述】:
namespace Y
{
  class foo { }
}
                    
namespace X.Z
{
  class bar : Y.foo { }
} // fine
                    
namespace X.Y.Z
{
  class bar2 : Y.foo { }
} // error!, now foo can't be found because it looks for X.Y.foo

这是一个 c# 错误吗?我会虽然在命名空间中只是在命名空间中声明的项目名称前面加上前缀。显然正在发生其他事情,我不确定这是一件好事。

【问题讨论】:

标签: c# namespaces


【解决方案1】:

所以

namespace X.Y.Z
{
  class bar2 : Y.foo { }
} 

只是以下的简写:

namespace X
{    
    namespace Y
    {        
        namespace Z
        {
          class bar2 : Y.foo { }
        }         
    }    
}

(希望很清楚为什么速记实际上很有价值。)

所以现在是时候尝试解析标识符Y.foo。 C# 这样做的方式是它总是查看可能的最窄范围,如果找不到合适的匹配项,它会向上移动一个级别。所以首先它会在bar2 的定义中查找,并没有找到合适的候选人。然后它进入下一个级别,直到命名空间X.Y.Z。然后再次升级到命名空间X.Y。现在我们有了 Y 可以匹配的东西,命名空间本身,它看起来与其中的标识符 foo 匹配,因为它是一个命名空间,然后再次发现什么都没有。

既然有 Y 匹配,那么它就完成了。每当标识符能够被解析时,即使它出错,它也不会继续搜索标识符可以解析为可能不会出错的其他事物。

根据需要解析标识符的一种方法是使用global:: 前缀,这是一个关键字,可以防止整个“由内而外”的事情发生,并强制标识符从根开始并工作一路向下,允许您编写 global::Y.foo; 并使其匹配您想要的类型。您还可以添加 using 来导入命名空间或为类型创建别名以正确解析类型。

当然,最好的解决方案是使用不同的命名空间名称来完全避免歧义问题,如果您可以控制的话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多