我在C#.NET Core 2.0中遇到了一些奇怪的东西,我想知道这里发生了什么。
我有一个名为FooBar.cs的文件,看起来像这个
namespace Foo
{
public class FooClass
{
}
namespace Bar
{
enum BarEnums
{
Bar1
,Bar2
,Bar3
}
}
}
我有一个看起来像这样的简单程序
using System;
using Foo;
namespace Using
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
FooClass fooClass = new FooClass();
Console.WriteLine(Bar.BarEnums.Bar1);
}
}
}
这给了我以下错误:
Program.cs(16,22): error CS0103: The name 'Bar' does not exist in the current context
我很困惑为什么using语句在名称空间中公开了类,但是它没有公开在同一级别找到的命名空间?如果我输入using Foo.Bar
它仍会给出相同的错误..所以using语句可以看到命名空间,但它无法帮助它找到下面的引用。
现在,如果我输入Foo.Bar.BarEnums.Bar1
它会正常工作..但为什么我不必按照与引用枚举相同的命名法放入Foo.FooClass
?这只是在命名空间中访问枚举与类之间的区别吗?
答案 0 :(得分:3)
这是因为using Foo
仅导入给定命名空间中包含的类型,但它并不专门导入嵌套的命名空间。这就是为什么当您引用enum
时必须使用完整的命名空间引用。
这是C#语言规范。
以下是来自C#团队成员的解释:
在C#中,指定“using”子句时,例如
使用System.Text;
编译器只将System.Text中的类型导入全局 命名空间 - 它对内部的任何命名空间都不做同样的事情 System.Text。所以,虽然这种使用允许我写:
StringBuilder s = new StringBuilder();
它不允许我写:
RegularExpressions.Regex r = new RegularExpressions.Regex();
为什么?
嗯,早期版本的C#编译器有这种行为,但我们 发现它有一些问题:
首先,它使代码更难以遵循。在上面的例子中, RegularExpressions.Regex()可以是全局名称,也可以是基于的名称 我的任何使用条款。必须查看代码的顶部 找出一个名字是我们想要避免的东西。
第二个问题与命名空间名称之间的冲突有关, 这种行为更经常发生。如果有的话 其中包含RegularExpressions命名空间的另一个命名空间, 用户将无法为两者都使用“使用”语句 - 甚至 如果他们实际上并不关心那个命名空间。
因此,我们决定改变行为。
这是C#规范:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/namespaces