在 C# 中,我global::
经常看到在自动生成的代码中使用。这不是我自己用过的东西,所以我不知道目的是什么。有人可以解释一下吗?
4 回答
global 指的是全局命名空间,它可以用来解决可以重新定义类型的问题。例如:
class foo
{
class System
{
}
}
如果您要使用 System ,它将在 foo 类中的本地范围内,您可以使用:
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
}
}
}
这是一个有时需要的前缀,指示根命名空间。
它通常被添加到生成的代码中,以避免名称与用户代码冲突。
例如,假设您有一个名为 的类System
,但您想使用System.String
. 你可以global::System.String
用来区分。
我相信::
它来自 C++,它被用作命名空间分隔符。
在实践中,除了生成代码之外,我从未使用过它。请注意,您还可以通过使用别名来解决一些冲突。例如using String = System.String;
上下文关键字,当global
它出现在 :: 运算符之前时,指的是全局命名空间,它是任何 C# 程序的默认命名空间,否则未命名。
说明global::
符告诉编译器从根开始寻找命名空间或类。您将在系统生成的代码中看到它,以便代码始终有效。这样,如果您在当前命名空间下有一个与代码尝试访问的顶级命名空间相同的命名空间,则不会发生冲突。
例如,假设您有命名空间 A、命名空间 B 和命名空间 BA,如果我在命名空间 BA 中编写需要引用命名空间 A 中的类的代码,而没有 global:: 我无法访问它。如果我引用 A.classname,编译器将在 BA 中查找类名 使用 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::
有助于您访问命名冲突。