嵌套命名空间的成员

3
假设命名空间A2嵌套在命名空间A1中,则A2是封闭的A1的成员。但是A2中声明的类型(因此在A2中声明的类型)不是A1的成员。
a) 什么是指A2的成员不是A1的成员?换句话说,如果它们也是A1的成员,会有什么不同?也许在A1内部,我们不必为在A2中定义的类型使用完全限定名称?
b) 命名空间A2成为A1的成员是什么意思?
顺便说一下-我确实了解命名空间,只是对我的书使用的术语感到困惑(即,A2是A1的成员等)。
编辑
1)因此,A2成为A1的成员是A1内部不需要为引用在A2中声明的类型指定A1.前缀的原因:
namespace A1
{
    class Program
    {
        static void Main(string[] args)
        {
            A2.classA2 a2= A2.classA2(); //here we don't need to include A1.
                                           prefix
        }
    }

    namespace A2
    {
       class classA2 { }
    }
}

2) 以下内容在 assembly asmLibrary.dll 中定义:

namespace A
{
    public class A1{}


    namespace B
    {
        public class B1{}
    }
}

下面的应用程序 App1 也引用了程序集 asmLibrary.dll:
namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            B.B1 instanceB1 = new B.B1();
        }
    }
}

以下应用程序 App2 引用了程序集 asmLibrary.dll:
using A;
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            A.B.B1 bInstance = new A.B.B1(); 

            A1 a1 = new A1();
        }
    }
}

a) 当我们试图在App2中声明A.B.B1的实例时,我们需要指定类型的完全限定名称。但是在App1中,我们可以通过B.B1指定类型。那么为什么我们可以在App1中省略A.前缀,而在App2中却不能呢?(App2有一个using A;指令,因此其行为应与App1相同。)
b) 另外,如果namespace Bnamespace A的成员,那么App2不应该允许我们使用B.B1 instanceB1 = new B.B1();语法声明类型A.B.B1吗?!
4个回答

3
请参考以下内容。
namespace A1
{
    namespace A2  // A1.A2
    {
        class C2  // full name: A1.A2.C2
        {
            private A1.C1 c1b;   // full name 
            private C1 c1b;      // shortest form. A1 is in scope here
        }
    }

    class C1   // full name: A1.C1
    {
        private A1.A2.C2 c2a;   // full name
        private A2.C2 c2b;      // shortest form. We can omit the A1 prefix but not A2
    }
}

答案

a) C2类不是A1的(直接)成员,因此在A2命名空间之外,我们必须将其声明为A2.C2 c2b;

b) A1的成员在A2内部范围内,参见C1 c1b;的声明


关于编辑:

您的示例显示了using a; ...namespace A { ... }的不同效果。

使用语句“从A导入类型 (§ 16.3.2)”,而在App2中,代码命名空间内。
这里的术语“成员”可能有点令人困惑。


基本上说,A2是A1的成员意味着在A1中引用A2中声明的类型时,我们不必指定A1前缀? - flockofcode
1
以下是一些额外的想法:
  1. 命名空间用于将类组织成逻辑集合。为了进一步组织事物,您可以“嵌套”命名空间:My.NamespaceMy.Namespace.Nested。但是这对运行时给定类型没有影响。在运行时,命名空间只是一个字符串,可能有也可能没有 .
  2. 命名空间影响的是编译期间的类型名称解析,它基于(简化)当前类型的命名空间和文件中的 using 语句。Henk 的示例很好地说明了这一点。
- marcind
1
@flockofcode:是的。A2和C1都是A1的成员,许多相同的规则适用。 - H H
据我所理解,如果C1也是A1的成员,则我们可以通过A1.C1而不仅仅是通过A1.A2.C1来引用C1。 - flockofcode
1
@flockofcode,我认为你应该再读一遍(-: A1.C1是正确的。 - H H
显示剩余3条评论

1

A2的成员是A2的成员 - “责任在此”。如果A1包含了A2成员的定义,那么什么也不会改变 - 无论如何,您都需要将这些成员引用为A1.member,将A2的成员引用为A1.A2.member - 除非您有using语句,否则如果想避免编译器错误,您需要小心处理。


1
  • 什么是A2命名空间作为A1成员的含义?

成员的含义在C#规范第3.4节中有所涵盖:

成员

命名空间和类型都有成员。实体的成员通常可以通过限定名称来访问,该限定名称以对实体的引用开头,后跟一个“.”标记,然后是成员的名称。

类型的成员要么在类型声明中声明,要么从类型的基类继承。[...]

“命名空间成员”的定义在第3.4.1节中给出:

命名空间成员

[...]

在命名空间中声明的命名空间和类型是该命名空间的成员。

  • A2的成员不是A1的成员的确切含义是什么?

这意味着仅因为A1.A2.Foo有效,并不意味着A1.Foo也有效。


你能再帮我一下吗?我修改了原始帖子。 - flockofcode

1
据我所知,IL 没有命名空间的概念。编译器将命名空间名称和类型名称附加在一起以组成更长的完整名称;例如,在命名空间 MyCompany.MyProduct 中的类 Customer 在编译为 IL 时将呈现为类似于 MyCompany$MyProduct$Customer 的形式。对于 IL 虚拟机来说,这是一个类型名称;它包含 $ 符号的事实是无关紧要的。
从这个事实中,你可以得出自己的结论。 :-)

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