我有两个不同的名称空间,每个名称空间都有一个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"”,那仍然是模棱两可的。看到我的观点?
答案 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.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;
允许在命名空间中使用类型,这样就不必限定在该命名空间中使用类型
对于别名,它没有提到命名空间使用的限定条件:
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
另见: