28

快速简单的问题。我有点理解命名空间别名限定符的作用,它用于访问命名空间中的成员,但是取消引用运算符也是如此。我真的很困惑这种情况下的区别,为什么你会使用一个而不是另一个,或者他们每个人如何完成同样的事情。

using colAlias = System.Collections;

namespace myns
{
    class TestApp
    {
        static void Main()
        {
            colAlias.Hashtable test = new colAlias.Hashtable();
            colAlias::Hashtable test1 = new colAlias::Hashtable();
        }
    }
}
4

5 回答 5

13

这是一个极端情况::(如@前缀),用于处理命名空间、类和关键字之间名称冲突的相当罕见的情况。

::仅适用于命名空间(和命名空间别名),而.. 适用于命名空间和子类。在您需要它的大多数地方,您最好使用不同的名称,但这并不总是一种选择。

global::是一种在自动生成的代码中最常见的特殊情况——它将引用的命名空间重置为根。

例如,假设您自动生成一些代码(可能用于表单应用程序、EF 或类似应用程序)并且您的应用程序使用命名空间YourCompany.Application。现在您的一位客户(使用您的自动生成)决定在他们的 app 中添加他们自己的命名空间TheirCompany.YourCompany.Application。现在您的所有自动代码都失败了,因为当它编译时.Net 不知道是使用您的名称空间还是使用他们的名称空间。

要使用 修复此生成代码global::YourCompany.Application,那么那些使用您的自动生成器的人可以使用他们喜欢的任何命名空间并且不会发生冲突。

我认为微软添加global::是因为他们希望一些 .Net 客户添加像 .Net 这样的命名空间System

于 2012-08-28T10:11:00.037 回答
6

你说:

命名空间别名限定符确实如此,它用于访问命名空间中的成员,但是取消引用运算符也是如此。

嗯,不。.运算符用于访问任何成员,包括函数。你不能Console::WriteLine();

::仅用于解析命名空间,或者来自这样的命名空间别名:

using colAlias = System.Collections;
...
...
colAlias::Hashtable test = new colAlias::Hashtable();

来自全球。

global::System.Console.WriteLine(..);

不能这样做:

System.Collections::ArrayList a = new System.Collections.ArrayList();

但是,如果您有别名,则.操作员也可以使用,因此在您的情况下,没有区别。

于 2012-08-28T07:11:13.860 回答
2

有一个MSDN 页面解释了它是如何工作的。

基本上,在您的情况下,它们将实现相同的目标,并且为了代码可读性,最好使用单个..

除了全局命名空间之外,我不会::在任何东西上使用运算符,即使这样,也有足够多的方法来解决它。

编辑:操作员所做的更多信息在:: Operator (C# Reference)文章中进行了解释。

于 2012-08-28T06:48:51.107 回答
1

命名空间限定符的一般思想是允许您引用命名空间,即使该名称已在其他地方使用过。如果您声明了一个名为“colAlias”的类,那么 colAlias.Hashtable 将引用该类,但 colAlias::Hashtable 将引用命名空间的值。

这是一个相当狭窄的用例,global::也是我见过的唯一典型的这个操作符用例(当试图确保在创建要在未知应用程序中编译的生成代码时不会发生冲突时)。

于 2012-08-28T06:50:29.633 回答
0

如果您有使用相同命名约定的 CONFLICTING 命名空间,命名空间别名限定符 (::) 可帮助您访问命名空间方法而不会导致错误。

例如,如 msdn http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx中所述

于 2012-08-28T06:49:23.573 回答