我在引用的项目Project.Base
中有一个命名空间,有人认为在该命名空间中声明自己的通用List类是个好主意。
现在我有一个开始的代码文件:
using System.Collections.Generic;
using Project.Base.Sub;
Project.Base
命名空间从未真正正式使用过;只是一个嵌套的命名空间。 System.Collections.Generic
正式使用。但由于一些奇怪的原因,当我声明一个返回类型为List<T>
的方法时,它会将其解释为Project.Base.List<T>
而不是System.Collections.Generic.List<T>
!
这对我来说似乎非常违反直觉。有谁知道发生了什么以及如何解决它?
编辑要重现:
using System;
using System.Collections.Generic;
using Project.Base.Sub;
namespace Project.Base
{
public class List<T> { }
}
namespace Project.Base.Sub { }
namespace Project.Base.Sub2
{
public class P
{
public static void Main()
{
var list = new List<int>();
Console.WriteLine(list.GetType().Namespace);
Console.Read();
}
}
}
(请注意,有问题的代码位于Project.Base的不同子命名空间中。这似乎很重要。)
答案 0 :(得分:2)
通过搜索封闭的命名空间继续进行名称查找,并且只考虑每个命名空间范围内的using
指令。
要进行此编译,您可以将using
指令移到其中:
using System;
namespace Project.Base
{
public class List<T> { }
}
namespace Project.Base.Sub { }
namespace Project.Base.Sub2
{
using System.Collections.Generic;
public class P
{
public static void Main()
{
var list = new List<int>();
Console.WriteLine(list.GetType().Namespace);
Console.Read();
}
}
}
顶级using
指令仅在全局命名空间内,因此只有在封闭命名空间中的查找失败时才会搜索。因此,第一次查找无法找到Project.Base.Sub2.List
,但在下一级别找到Project.Base.List
。如果失败了,它会尝试找到Project.List
类型。
另一个using
指令是红鲱鱼。
答案 1 :(得分:2)
接受的答案是正确的。理解该问题的另一种方法是您发布的代码完全等同于
using System;
using System.Collections.Generic;
using Project.Base.Sub;
namespace Project
{
namespace Base
{
public class List<T> { }
namespace Sub { }
namespace Sub2
{
public class P
{
public static void Main()
{
var list = new List<int>();
Console.WriteLine(list.GetType().Namespace);
Console.Read();
}
}
}
}
}
现在应该清楚为什么List
会像它一样解决。 List
的声明直接在一个封闭的命名空间中。
从设计的角度来看,最好还是让你的同事回过头来,这个同事认为命名一个班级&#34; List&#34;是个好主意。通常声明存在名称空间以防止名称冲突,但这实际上是它们的次要目的。在现实的代码中,通常没有太多的命名冲突,因为人们通常不会做一些令人困惑的事情,例如命名他们自己的类&#34; List&#34;。
命名空间的主要目的是将代码组织成逻辑组,以便您可以使用using
来进入范围&#34;您可能在程序中使用的内容的名称。这使IntelliSense可以更好地确定您在键入内容时的含义,使代码更易于阅读,等等。如果您发现自己使用命名空间来防止命名冲突,则可能需要考虑是否可以通过某些战术重命名来消除这些冲突。