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

Why does adding a namespace alias in C# remove ambiguity?

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

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

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

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

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;

现在,当我执行 var x = new Thing();.

时,编译器认为我指的是 Fourth.Fifth.Sixth.Thing

为什么编译器只是通过向其中一个命名空间添加别名来解决歧义?为什么它会自动选择我没有别名的名称空间?

我希望这会在 SO 和其他地方得到很好的记录和多次介绍,但我找不到答案。有人可以帮我找到骗子吗?

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

如果我有两个人叫"Bob",我就说"here, give this to Bob",你就不知道该给谁了。如果我说,一个是 "Bob Smith",另一个是 "Bob Johnson",当然我现在可以说 "here, give this to Bob Smith." 现在,如果我说 "let's call Bob Smith by a new name: Bob Brady"。如果我然后说“在这里,把这个给 "Bob",那仍然是模棱两可的。明白我的意思吗?

我认为您混淆了 x 别名和 x 变量。因为你在 First.Second.Third 中使用 x 作为别名,如果你想使用那个东西,那么你应该使用

var aThing = new x.Thing();

HTH, 迈克

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

如果您引用 Thing,它将默认使用非别名版本(除非您特别使用别名)。如果您使用 using System.

,这 Console.ReadLine 的工作方式 完全相同

见下文。

namespace Test
{
    using MyAlias = First.Second.Third;
    using Fourth.Fifth.Sixth;

    public class Program
    {
        static void Main()
        {
            var x = new Thing(); // non aliased
            var y = new MyAlias.Thing(); // aliased
            Console.ReadLine();
        }

    }
}

另请参阅:

我认为您的误解是您认为别名会自动导入名称空间的类型。

using Fourth.Fifth.Sixth;

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

using MyAlias = First.Second.Third;

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

导入 Thing

另见C# 5.0 Language Specification中的相应定义:

A using-alias-directive (§9.4.1) introduces an alias for a namespace or type.

A using-namespace-directive (§9.4.2) imports the type members of a namespace.

事情是这样的:

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;

To allow the use of types in a namespace so that you do not have to qualify the use of a type in that namespace

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

using Project = PC.MyCompany.Project;

To create an alias for a namespace or a type