C# 命名空间别名限定符 (::) 与取消引用运算符 (.)

Posted

技术标签:

【中文标题】C# 命名空间别名限定符 (::) 与取消引用运算符 (.)【英文标题】:C# Namespace Alias qualifier (::) vs Dereferencing Operator (.) 【发布时间】:2012-08-22 15:34:56 【问题描述】:

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

using colAlias = System.Collections;

namespace myns

    class TestApp
    
        static void Main()
        
            colAlias.Hashtable test = new colAlias.Hashtable();
            colAlias::Hashtable test1 = new colAlias::Hashtable();
        
    

【问题讨论】:

+1 只是因为我已经用 C# 编程了几年,而且我从未见过在任何地方使用过这个运算符。 :D @Tudor 也有同样的情况 :) 很少见到,但我今天遇到了,想了解更多。 【参考方案1】:

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

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

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

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

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

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

【讨论】:

我认为微软添加了 global:: 因为 ... 不完全是:“您可能必须引用具有相同完全限定类型名称的程序集的两个版本” 【参考方案2】:

你说:

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

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

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

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

OR 来自全球。

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

不能这样做:

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

但是,如果您有别名,. 运算符也可以使用,所以在您的情况下,没有区别。

【讨论】:

这是否意味着. 操作符可以做:: 操作符可以做的所有事情,甚至更多,除了引用全局命名空间?【参考方案3】:

有一个MSDN page 解释它是如何工作的。

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

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

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

命名空间别名限定符 (::) 可帮助您在使用相同命名约定的命名空间存在冲突时访问命名空间方法而不会导致错误。

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

【讨论】:

嗯,谢谢你的回答,但我自己想了这么多,请阅读我的描述。我想知道的是区别,例如,为什么你不能使用解引用运算符来访问全局命名空间......为什么你会使用一个而不是另一个...... @FranciscoAguilera 假设您有自己的 System 类。在这种情况下,如果您愿意,您将如何使用取消引用运算符来访问 System.Console.WriteLine?因此,您使用命名空间别名限定符来访问全局命名空间( global::System.Console.WriteLine() )以避免冲突。

以上是关于C# 命名空间别名限定符 (::) 与取消引用运算符 (.)的主要内容,如果未能解决你的问题,请参考以下文章

类型 spatial_geometry 未使用命名空间或别名进行限定。只有原始类型可以在没有限定的情况下使用

C#部分语法总结

PHP使用命名空间:别名/导入(Aliasing/Importing)

C# using的用法

C# 关键字--using

PHP命名空间的三种引用方式:非限定名称限定名称完全限定名称