【发布时间】:2013-02-07 23:14:17
【问题描述】:
在 C# 中,我看到 global:: 在自动生成的代码中经常使用。这不是我自己用过的东西,所以我不知道目的是什么。有人可以解释一下吗?
【问题讨论】:
标签: c#
在 C# 中,我看到 global:: 在自动生成的代码中经常使用。这不是我自己用过的东西,所以我不知道目的是什么。有人可以解释一下吗?
【问题讨论】:
标签: c#
这是一个有时需要的前缀,表示根命名空间。
它通常被添加到生成的代码中以避免名称与用户代码冲突。
例如,假设您有一个名为System 的类,但您想使用System.String。您可以使用global::System.String 来区分。
我相信:: 来自 C++,它被用作命名空间分隔符。
实际上,除了生成代码之外,我从未使用过它。请注意,您还可以通过使用别名来解决一些冲突。例如using String = System.String;
【讨论】:
global 指的是全局命名空间,它可以用来解决可以重新定义类型的问题。例如:
class foo
{
class System
{
}
}
如果您要在 foo 类的本地范围内使用 System,您可以使用:
global::System.Console.WriteLine("foobar");
访问全局命名空间。
示例
using System;
class Foo
{
public void baz()
{
Console.WriteLine("Foo 1");
}
}
namespace Demo
{
class Foo
{
public void baz()
{
Console.WriteLine("Foo 2");
}
}
class Program
{
protected static global::Foo bar = new global::Foo();
static void Main(string[] args)
{
bar.baz(); // would write Foo 1 to console as it refers to global scope
Foo qux = new Foo();
qux.baz(); // would write Foo 2 to the console as it refers to the Demo namespace
}
}
}
【讨论】:
global 上下文关键字,当它出现在 :: 运算符之前时,指的是全局命名空间,这是任何 C# 程序的默认命名空间,否则未命名。
global:: 说明符告诉编译器从根开始寻找命名空间或类。您将在系统生成的代码中看到它,以便代码始终有效。这样,如果您在当前命名空间下有一个与代码尝试访问的顶级命名空间相同的命名空间,就不会发生冲突。
例如,假设您有命名空间 A、命名空间 B 和命名空间 B.A,如果我在命名空间 B.A 中编写需要引用命名空间 A 中的类的代码,而没有 global:: 我无法访问它。如果我引用 A.classname,编译器将在 B.A. 中查找类名。使用 global:: 我可以告诉它在 global::A.classname 中查找类名,它会在正确的位置找到类名。
【讨论】:
global:: 命名空间及其标识符并不是大多数人所想的。它不是应用程序中创建的所有内容的通用标识符,该标识符位于应用程序定义的命名空间之一之外,并且附加到某个全局根目录。
如果您在顶级命名空间之外创建一个类或类型,您将假定它自动成为 GLOBAL 命名空间的一部分,并且可以通过应用程序或程序集中的所有文件中的 global:: 标识符访问。实际上,这些名称通常仅在该文件的已编译 LOCAL 范围内,但可通过 global:: 标识符访问。
如果您在 aspx.cs 文件中创建顶级类或命名空间,则可以从该文件中的全局命名空间通过 global:: 访问它。但是,如果您在另一个文件中键入 global::,则该类和命名空间在全局命名空间中不存在。但是,如果您在 class.cs 文件中创建相同的类或命名空间,则这些项目可通过 global:: 和在全局命名空间以及该文件的本地范围内的所有其他文件中使用。为什么?
事实证明,global:: 实际上是对文件范围内的顶级 LOCAL 名称以及程序集共享的 GLOBAL 名称的引用(就像在典型 ASP.NET 项目中的 App_Code 类文件中可能编译的内容一样) .
我发现这非常令人困惑且不一致,因为global:: 意味着可以访问在应用程序中创建的与全局命名空间相关的顶级命名空间和类型。默认情况下,像“系统”这样的一些文件在所有文件中都与全局命名空间相关联,但自定义文件可能取决于该文件的范围,也可能不取决于该文件的范围。这就是为什么全局标识符在解析对本地根范围名称的引用方面也具有次要作用。
您可以通过在应用程序的某些部分中创建顶级命名空间和类然后使用global:: 来查看它可以从应用程序的不同部分访问全局命名空间中的哪些,以及不能访问哪些。它无法访问的仅在该文件中明确分配给“本地全局范围”,global:: 可帮助您在命名冲突中访问。
【讨论】: