【问题标题】:How to avoid seemingly automatic reference of "parent" namespaces?如何避免看似自动引用“父”命名空间?
【发布时间】:2020-12-31 20:34:50
【问题描述】:

我相信我对命名空间层次结构有一个根本的误解,导致这个问题几乎相反的问题:vb.net System namespace conflict with sibling namespace

我有两个 .cs 文件,其中包含以下内容:

文件 1

namespace Parent.Math
{
    public class Foo { }
}

文件 2

using System;
namespace Parent.Child
{
    public class Bar
    {
        public Bar()
        {
            Console.WriteLine(Math.Sqrt(4));           
        }
    }
}

文件 2 出现错误:CS0234 - The type or namespace name 'Sqrt' does not exist in the namespace 'Parent.Math'

为什么编译器假定Math 是对同级命名空间的引用,而不是显式引用的System 命名空间的成员?行为就像自动引用父命名空间一样。它是否正确?我至少会预料到一个模棱两可的错误。

谢谢。

【问题讨论】:

  • 我记得在某处读到过,在搜索名称时,它总是从当前命名空间开始。
  • “这种行为就像是自动引用了父命名空间一样。这是否正确?”是的。
  • 或将 using System; 放在命名空间内。如果你想知道血淋淋的细节,14.5.3 Using namespace directives 在 ecma 规范中
  • Any reason why this would be "bad practice"? 部分是因为它使代码更难审查(相对于明确System)。但老实说,由于冲突,这将很难审查。
  • @GeorgeKerwood 我对 ecma 的引用有点乐观,分辨率实际上分散在几个主题之外。关于在编译单元中应该使用包含使用还是全局使用,有 2 种学派。两者都有好处,只要您始终如一,我都不会认为这是不好的做法。

标签: c# visual-studio namespaces


【解决方案1】:

当你在一个命名空间中时,编译器总是假设你也在父命名空间中。

因此在 Parent.Child 中写入 Math 时,编译器在 Child 中搜索,然后在 Parent 中搜索,发现 Math 作为命名空间但没有 Sqrt 类型,所以出现错误。

编译器会这样搜索并沿着命名空间链向上。

没有命名空间,你在global

你可以简单地写:

Console.WriteLine(System.Math.Sqrt(4));           

或者如果出现问题:

Console.WriteLine(global::System.Math.Sqrt(4));

你也可以写:

using SystemMath = System.Math;

Console.WriteLine(SystemMath.Sqrt(4));

从 C# 6 开始:

using static System.Math;

Console.WriteLine(Sqrt(4));

https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive

【讨论】:

  • 谢谢。我知道解决方案选项(别名和完全限定名称)。我真的想了解为什么在显式引用之上提升父命名空间,或者至少为什么没有引发歧义错误。我从 cmets 那里得到了我的答案,你在这里的回答可能对某人有用。
  • 太好了,这就是答案,谢谢。也许包括在命名空间中包含 using 语句的选项以确保完整性?根据@MichaelRandall 的评论。
猜你喜欢
  • 2022-12-25
  • 2016-02-18
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多