为什么在C#中添加命名空间别名会消除歧义?

时间:2017-06-13 13:52:26

标签: c# namespaces alias ambiguous using-directives

我有两个不同的名称空间,每个名称空间都有一个Thing类:

namespace First.Second.Third
{
    public class Thing { }
}

namespace Fourth.Fifth.Sixth
{
    public class Thing { }
}

现在我尝试在其他地方使用Thing,当然编译器因为对该类的模糊引用而抱怨:

namespace ConsoleApp1
{
    using First.Second.Third;
    using Fourth.Fifth.Sixth;

    internal static class MainEntryPoint
    {
        internal static void Main(string[] args)
        {
            var x = new Thing(); // Complaint.
        }
    }
}

如果我在using指令中的一个名称空间中添加别名,编译器错误就会消失:

using MyAlias = First.Second.Third;
using Fourth.Fifth.Sixth;

现在编译器认为我在Fourth.Fifth.Sixth.Thing时引用var x = new Thing();

为什么编译器只需在其中一个命名空间中添加别名即可解决歧义?为什么它会自动选择我没有别名的命名空间?

我希望在SO和其他地方之前有很多文档记录和覆盖,但我无法找到答案。如果有人可以帮我找到傻瓜吗?

编辑:我猜不到每个人都在同一页面上。这是一个可能有用的真实示例:

如果我有两个人名为" Bob",我只是说"在这里,把它交给Bob",你不会知道该给谁。如果我说,那么一个是#34; Bob Smith"另一个是" Bob Johnson"当然我现在可以说"在这里,把它交给Bob Smith。"现在,如果我说,"让我们用一个新名字给Bob Smith打电话:Bob Brady"。如果我然后在这里说“#34; Bob"”,那仍然是模棱两可的。看到我的观点?

4 个答案:

答案 0 :(得分:9)

我认为您的错误观念是您认为别名会自动导入命名空间的类型。

using Fourth.Fifth.Sixth;

使此命名空间中的所有类型都可见,无需额外限定。

using MyAlias = First.Second.Third;

除了为命名空间赋予新名称​​而不用导入它之外什么都不做。因此,如果您将using First.Second.Third;更改为using MyAlias = First.Second.Third;,则会删除歧义,因为Thing中的First.Second.Third在没有进一步限定的情况下不再可见。但很明显,其他using仍然从Thing导入Fourth.Fifth.Sixth

另请参阅C# 5.0 Language Specification中的相应定义:

  

using-alias-directive (§9.4.1)引入了名称空间的别名   或者输入。

     

using-namespace-directive (第9.4.2节)导入类型成员   命名空间。

答案 1 :(得分:2)

这就是你做的事情:

using First.Second.Third;
using Fourth.Fifth.Sixth;

现在First.Second.ThirdFourth.Fifth.Sixth中的所有内容都可以在没有完全限定名称的情况下引用。这包括Thing,但由于两者都包含Thing,因此new Thing()的含义不明确。

如果你这样做:

using First.Second.Third;
using MySixth = Fourth.Fifth.Sixth;

然后只有First.Second.Third可以在没有完全限定名称的情况下被引用,名称空间Fourth.Fifth.Sixth也称为MySixth,因此没有歧义。

请注意以下措辞: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive

对于第一种情况,它确实说:

  

using System.Text;

     

允许在命名空间中使用类型,这样就不必限定在该命名空间中使用类型

对于别名,它没有提到命名空间使用的限定条件:

  

using Project = PC.MyCompany.Project;

     

为命名空间或类型

创建别名

答案 2 :(得分:0)

我相信你将x别名与x变量混淆了。因为你在First.Second.Third中使用x作为别名,如果你想使用Thing那么你应该使用

//... .data<INode>(graph.nodes) // Commenting this out, error goes away .enter() .append<SVGCircleElement>("circle") //...

HTH, 麦克

答案 3 :(得分:0)

通过在第一个选项上添加别名,您已经有效地解决了歧义(现在还有两个Thing - 有一个Thing和一个MyAlias.Thing)。

如果您引用Thing,它将默认使用非别名版本(除非您专门使用别名)。如果您使用Console.ReadLine,{{1>}的工作方式完全相同

见下文。

using System

另见: