为什么我可以访问定义在命名空间外部的类?

4

我想知道为什么我可以在命名空间范围之外定义类并访问它?

我对命名空间不是很熟悉,正在学习中。但我认为命名空间应该像将所有类包装在一个“盒子”中,它们只能在这个“盒子”(作用域)内相互访问。

代码示例:

class Point
{
    public int X;
}

namespace ConsoleApplication12
{
    class Program
    {
        static void Main(string[] args)
        {
            Point p = new Point();
            p.X = 50;
            Console.WriteLine(p.X);
            Console.ReadLine();
        }
    }
}

感谢您的回答。

你是否已经import了_Point_类所在的命名空间? - Balagurunathan Marimuthu
@BalagurunathanMarimuthu: Point 类不在命名空间中。 这就是关键。 - Jon Skeet
2个回答

8
命名空间与访问权限无关。重要的是要区分命名空间和程序集,它们通常密切相关,因为命名空间Foo.Bar中的类型可能会在程序集Foo.Bar.dll中,但这只是一种约定,编译器或语言并不关心。
命名空间主要是“名称必须唯一的空间”。换句话说,虽然有两个不同命名空间下都有一个名为Point的类型是可以的,但在同一个命名空间下不能有两个名为Point的类型。实际上,命名空间存在的主要原因(我认为)是为了使我们不必在全球所有.NET代码中使用完全独特的名称。
如果Point类被隐式声明为internal且在同一程序集中声明,则可以使用它。如果它在全局命名空间中(即根本没有在命名空间中声明),则您不需要任何using指令来引用它。 using指令的目的是允许您通过其简短名称引用不同命名空间的成员。
所以,如果你有:
namespace Foo.Bar
{
    public class Baz {}
}

那么你可以通过以下两种方式来访问它:

namespace Other
{
    class Test
    {
        Foo.Bar.Baz baz = new Foo.Bar.Baz();
    }
}

或者

// Allow anything in namespace Foo.Bar to be accessed by its
// short name
using Foo.Bar;

namespace Other
{
    class Test
    {
        Baz baz = new Baz();
    }
}

如果类型是在“全局”命名空间中定义的,那么你就不需要using指令。在C# 5语言规范第3.8节(命名空间和类型名称)中描述了类型名称查找过程:

如果前面的步骤均失败,则对于每个命名空间N,从包含命名空间或类型名称的命名空间开始,继续每个封闭命名空间(如果有),直到全局命名空间,评估以下步骤,直到找到实体。

所以在您的情况下,从您的Main方法寻找Point,首先检查ConsoleApplication12是否有Point类型,然后检查全局命名空间。

0

要在命名空间外访问类,你的类应该是公共的。

public class Point

在你的命名空间中,如果你想要看到这个类,你需要在使用之前先在代码顶部添加命名空间。

using mynamespace.external;

然后你就可以访问你的类


4
只要访问代码在同一个程序集中,它可以是内部的(默认情况下),不一定需要公开。 - Jon Skeet
听起来不错,但我想知道为什么我的代码没有做这个也能工作。我只是在命名空间之外定义了一个类,而且我还能在命名空间内创建该类的对象。 - Jakub Gause
@JakubGause:让我困惑的是,你为什么认为它不应该工作。你可能习惯了使用来自其他命名空间的类型...这只是全局命名空间。你为什么期望它失败? - Jon Skeet
抱歉,我的错误。Point类与当前文件在同一个文件中,我现在明白了。所以它会起作用。我假设它在不同的命名空间的不同文件中。是的,通常我会使用许多命名空间并且不会跳出它们。 - raichiks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接