ti-enxame.com

O que é global ::?

Em C #, vejo global:: usado com bastante frequência no código gerado automaticamente. Não é algo que eu já usei, então não sei qual é o propósito. Alguém pode explicar isso?

96
Sachin Kainth

global refere-se ao espaço para nome global, ele pode ser usado para resolver problemas nos quais você pode redefinir tipos. Por exemplo:

class foo
{
    class System
    {

    }

}

Se você fosse usar o System onde ele teria um escopo local na classe foo, você poderia usar:

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

para acessar o espaço para nome global.

Exemplo

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
        }
    }
}
87
chrisw

É um prefixo necessário para indicar o espaço para nome raiz.

É frequentemente adicionado ao código gerado para evitar conflitos de nome com o código do usuário.

Por exemplo, imagine que você tinha uma classe chamada System, mas queria usar System.String. Você pode usar global::System.String para diferenciar.

Eu acredito que o :: vem do C++, onde é usado como um separador de namespace.

Na prática, nunca o usei, além de gerar código. Observe que você também pode contornar alguns conflitos usando aliases. Por exemplo using String = System.String;

21
Drew Noakes

A palavra-chave contextual global, quando vem antes do operador ::, refere-se ao espaço para nome global, que é o espaço para nome padrão para qualquer programa C # e, de outra forma, não tem nome.

O especificador global:: diz ao compilador para começar a procurar o espaço para nome ou classe a partir da raiz. Você o verá no código gerado pelo sistema para que o código sempre funcione. Dessa forma, se você tiver um espaço para nome logo abaixo do espaço para nome atual igual ao espaço para nome de nível superior que o código está tentando acessar, não haverá conflito.

Por exemplo, digamos que você tenha o namespace A e o namespace B e o namespace B.A se eu escrever um código no namespace B.A que precise fazer referência a uma classe no namespace A, sem global :: Eu não tenho como chegar a ele. Se eu referenciar A.classname, o compilador procurará o nome da classe em B.A. Com global :: eu posso dizer para procurar o nome da classe em global :: A.classname e ele encontrará o nome da classe no local apropriado.

12
coder

O espaço de nome global:: e seu identificador não é o que a maioria das pessoas pensa. Não é um identificador universal de tudo o que é criado em um aplicativo que fica fora de um dos namespaces definidos pelo aplicativo e que está anexado a alguma raiz global.

Se você criar uma classe ou tipo fora dos seus namespaces de nível superior, você assumirá automaticamente uma parte do namespace GLOBAL e acessível pelo identificador global:: em todos os arquivos em seu aplicativo ou Assembly. Na verdade, esses nomes estão mais frequentemente no escopo LOCAL compilado desse arquivo, mas podem ser acessados ​​pelo identificador global::.

Se você criar uma classe ou namespace de nível superior em um arquivo aspx.cs, ele poderá ser acessado via global:: no namespace global desse arquivo. Mas se você digitar global:: em outro arquivo, essa classe e espaço para nome não existirão no espaço para nome global. Se você criar a mesma classe ou espaço para nome em um arquivo class.cs, esses itens estarão disponíveis para todos os outros arquivos via global:: e no espaço para nome global, bem como no escopo local dos arquivos. Por quê?

Acontece que global:: é realmente uma referência aos nomes LOCAL de nível superior no escopo do arquivo, bem como aos nomes GLOBAL compartilhados pelo Assembly (como o que pode ser compilado nos arquivos de classe App_Code em um projeto típico do ASP.NET).

Achei isso muito confuso e não consistente, uma vez que global:: implica acesso aos espaços para nome e tipos de nível superior criados no aplicativo que estão vinculados ao espaço para nome global. Alguns como "Sistema" estão vinculados ao espaço para nome global por padrão em todos os arquivos, mas os personalizados podem ou não depender do escopo desse arquivo. É por isso que o identificador global também tem uma função secundária de resolver referências aos nomes de escopo raiz local.

Você pode testar isso criando namespaces e classes de nível superior em partes do seu aplicativo e usando global:: para ver quais eles podem acessar no namespace global de diferentes partes do seu aplicativo e quais não podem. A pessoa que ele não pode acessar é claramente atribuída a um "escopo global local" somente nesse arquivo, o qual global:: ajuda a acessar conflitos de nomeação.

1
Stokely