为什么在 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();
}
}
}
另请参阅:
- https://msdn.microsoft.com/en-us/library/aa664765(v=vs.71).aspx
- https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive
- C# namespace alias - what's the point?
我认为您的误解是您认为别名会自动导入名称空间的类型。
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.Third
和 Fourth.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
我有两个不同的命名空间,每个命名空间都有一个 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();
}
}
}
另请参阅:
- https://msdn.microsoft.com/en-us/library/aa664765(v=vs.71).aspx
- https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive
- C# namespace alias - what's the point?
我认为您的误解是您认为别名会自动导入名称空间的类型。
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.Third
和 Fourth.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