Compartilhar via


A diretiva using

A diretiva using permite que você use os tipos definidos em um namespace, sem especificar o namespace totalmente qualificado desse tipo. Na forma básica, a diretiva using importa todos os tipos de um único namespace, conforme mostrado no exemplo a seguir:

using System.Text;

Você pode aplicar dois modificadores a uma diretiva using:

  • O modificador global tem o mesmo efeito que adicionar a mesma diretiva using a cada arquivo de origem do projeto. Esse modificador foi introduzido no C# 10.
  • O modificador static importa os membros static e tipos aninhados de um único tipo, em vez de importar todos os tipos em um namespace.

Você pode combinar os dois modificadores para importar os membros estáticos de um tipo para todos os arquivos de origem em seu projeto.

Você também pode criar um alias para um namespace ou um tipo com uma diretiva using alias.

using Project = PC.MyCompany.Project;

Você pode usar o modificador global em uma diretiva using alias.

Observação

A palavra-chave using também é usada para criar instruções using, o que ajuda a garantir que objetos IDisposable, tais como arquivos e fontes, sejam tratados corretamente. Para obter mais informações sobre a instrução using, consulte instrução using.

O escopo de uma diretiva using, sem o modificador global, é limitado ao arquivo em que ele aparece.

A global using diretiva deve aparecer antes de todas as declarações de namespace e tipo. Todas as diretivas globais using devem aparecer em um arquivo de origem antes de quaisquer diretivas não globais using .

Outras using diretivas podem aparecer:

  • No início de um arquivo de código-fonte, antes de quaisquer declarações de namespace ou de tipo.
  • Em qualquer namespace com escopo bloqueado, mas antes de qualquer namespace ou tipo declarado nesse namespace.

Caso contrário, um erro do compilador será gerado.

Crie uma diretiva using para usar os tipos em um namespace sem precisar especificar o namespace. Uma diretiva using não fornece acesso a namespaces aninhados no namespace especificado. Os namespaces vêm em duas categorias: definidos pelo usuário e definidos pelo sistema. Os namespaces definidos pelo usuário são namespaces definidos em seu código. Para obter uma lista dos namespaces definidos pelo sistema, consulte Navegador de API do .NET.

O global modificador

Adicionar o modificador global a uma diretiva using significa que o uso é aplicável a todos os arquivos na compilação (normalmente um projeto). A diretiva global using foi adicionada no C# 10. Sua sintaxe é:

global using <fully-qualified-namespace>;

Onde fully-qualified-namespace é o nome totalmente qualificado do namespace cujos tipos podem ser referenciados sem especificar o namespace.

Uma diretiva global using pode aparecer no início de qualquer arquivo de código-fonte. Todas as diretivas global using em um único arquivo devem aparecer antes:

  • Todas as diretivas using sem o modificador global.
  • Todas as declarações de namespace e de tipo no arquivo.

Você pode adicionar global using diretivas a qualquer arquivo de origem. Normalmente, você deseja mantê-los em um único local. A ordem das diretivas global using não importa, seja em um único arquivo ou entre arquivos.

O global modificador pode ser combinado com o static modificador. O global modificador pode ser aplicado a uma diretiva using alias. Em ambos os casos, o escopo da diretiva inclui todos os arquivos na compilação atual. O exemplo a seguir permite o uso de todos os métodos declarados no System.Math em todos os arquivos do projeto:

global using static System.Math;

Você também pode incluir globalmente um namespace, adicionando um item <Using> ao arquivo de projeto, por exemplo, <Using Include="My.Awesome.Namespace" />. Para obter mais informações, confira Item <Using>.

Os analisadores emitirão diagnósticos se você duplicar global diretivas using em locais diferentes. Esses mesmos analisadores também informam se você adiciona uma using diretiva para um namespace ou tipo que uma global diretiva using já faz referência. Você pode achar mais fácil gerenciar seus global usos mantendo-os juntos em um arquivo no projeto.

Importante

Os modelos C# para o .NET 6 usam instruções de nível superior. Se você já tiver atualizado para o .NET 6, talvez seu aplicativo não corresponda ao código descrito neste artigo. Para obter mais informações, consulte o artigo sobre Novos modelos C# geram instruções de nível superior

O SDK do .NET 6 também adiciona um conjunto de diretivas implícitas global usingpara projetos que usam os seguintes SDKs:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

Essas diretivas implícitas global using incluem os namespaces mais comuns para o tipo de projeto.

Para obter mais informações, consulte o artigo sobre Diretivas de uso implícito

O static modificador

A diretiva using static nomeia um tipo cujos membros estáticos e tipos aninhados podem ser acessados sem especificar um nome de tipo. Sua sintaxe é:

using static <fully-qualified-type-name>;

O <fully-qualified-type-name> é o nome do tipo cujos membros estáticos e tipos aninhados podem ser referenciados sem especificar um nome de tipo. Se você não fornecer um nome de tipo totalmente qualificado (o nome do namespace completo juntamente com o nome do tipo), o C# gerará o erro de compilador CS0246: “O tipo ou o nome do namespace 'type/namespace' não pôde ser encontrado (uma diretiva using ou uma referência de assembly está ausente?)”.

A diretiva using static aplica-se a qualquer tipo que tenha membros estático (ou tipos aninhados), mesmo que ele também tenha membros de instância. No entanto, os membros da instância podem ser invocados apenas por meio de instância de tipo.

Você pode acessar os membros estáticos de um tipo sem precisar qualificar o acesso com o nome do tipo:

using static System.Console;
using static System.Math;
class Program
{
    static void Main()
    {
        WriteLine(Sqrt(3*3 + 4*4));
    }
}

Normalmente, quando você chamar um membro estático, fornece o nome do tipo juntamente com o nome do membro. Inserir repetidamente o mesmo nome de tipo para invocar os membros do tipo pode resultar em código obscuro detalhado. Por exemplo, a seguinte definição de uma classe Circle referencia vários membros da classe Math.

using System;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * Math.PI; }
   }

   public double Area
   {
      get { return Math.PI * Math.Pow(Radius, 2); }
   }
}

Ao eliminar a necessidade de referenciar explicitamente a classe Math, sempre que um membro é referenciado, a diretiva using static produz um código mais limpo:

using System;
using static System.Math;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * PI; }
   }

   public double Area
   {
      get { return PI * Pow(Radius, 2); }
   }
}

using static importa somente os membros estáticos acessíveis e os tipos aninhados declarados no tipo especificado. Os membros herdados não são importados. Você pode importar de qualquer tipo nomeado com uma diretiva using static, incluindo módulos do Visual Basic. Se funções de nível superior do F# aparecerem nos metadados como membros estáticos de um tipo nomeado cujo nome é um identificador válido do C#, as funções do F# poderão ser importadas.

using static torna os métodos de extensão declarados no tipo especificado disponível para pesquisa de método de extensão. No entanto, os nomes dos métodos de extensão não são importados no escopo para a referência não qualificada no código.

Métodos com o mesmo nome importados de diferentes tipos por diferentes diretivas using static na mesma unidade de compilação ou namespace formam um grupo de métodos. A resolução de sobrecarga nesses grupos de métodos segue as regras normais de C#.

O exemplo a seguir usa a diretiva using static para tornar os membros estáticos das classes Console, Math e String disponíveis sem a necessidade de especificar seu nome de tipo.

using System;
using static System.Console;
using static System.Math;
using static System.String;

class Program
{
   static void Main()
   {
      Write("Enter a circle's radius: ");
      var input = ReadLine();
      if (!IsNullOrEmpty(input) && double.TryParse(input, out var radius)) {
         var c = new Circle(radius);

         string s = "\nInformation about the circle:\n";
         s = s + Format("   Radius: {0:N2}\n", c.Radius);
         s = s + Format("   Diameter: {0:N2}\n", c.Diameter);
         s = s + Format("   Circumference: {0:N2}\n", c.Circumference);
         s = s + Format("   Area: {0:N2}\n", c.Area);
         WriteLine(s);
      }
      else {
         WriteLine("Invalid input...");
      }
   }
}

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * PI; }
   }

   public double Area
   {
      get { return PI * Pow(Radius, 2); }
   }
}
// The example displays the following output:
//       Enter a circle's radius: 12.45
//
//       Information about the circle:
//          Radius: 12.45
//          Diameter: 24.90
//          Circumference: 78.23
//          Area: 486.95

No exemplo, a using static diretiva também pode ser aplicada ao Double tipo. Adicionar essa diretiva tornaria possível chamar o método TryParse(String, Double) sem especificar um nome de tipo. No entanto, usar TryParse sem um nome de tipo cria um código menos legível, pois torna-se necessário verificar as diretivas using static para determinar qual método TryParse do tipo numérico é chamado.

using static também se aplica aos tipos enum. Ao adicionar using static com a enumeração, o tipo não é mais necessário para usar os membros de enumeração.

using static Color;

enum Color
{
    Red,
    Green,
    Blue
}

class Program
{
    public static void Main()
    {
        Color color = Green;
    }
}

O using alias

Crie uma diretiva de alias using para tornar mais fácil a qualificação de um identificador para um namespace ou tipo. Em qualquer diretiva using, o namespace totalmente qualificado ou o tipo deve ser usado independentemente das diretivas using que vêm antes. Nenhum alias using pode ser usado na declaração de uma diretiva using. Por exemplo, o exemplo a seguir gera um erro do compilador:

using s = System.Text;
using s.RegularExpressions; // Generates a compiler error.

O exemplo a seguir mostra como definir e usar um alias de using para um namespace:

namespace PC
{
    // Define an alias for the nested namespace.
    using Project = PC.MyCompany.Project;
    class A
    {
        void M()
        {
            // Use the alias
            var mc = new Project.MyClass();
        }
    }
    namespace MyCompany
    {
        namespace Project
        {
            public class MyClass { }
        }
    }
}

Uma diretiva using alias não pode ter um tipo genérico aberto no lado direito. Por exemplo, você não pode criar um using alias para um List<T>, mas pode criar um para um List<int>.

O exemplo a seguir mostra como definir uma diretiva using e um alias using para uma classe:

using System;

// Using alias directive for a class.
using AliasToMyClass = NameSpace1.MyClass;

// Using alias directive for a generic class.
using UsingAlias = NameSpace2.MyClass<int>;

namespace NameSpace1
{
    public class MyClass
    {
        public override string ToString()
        {
            return "You are in NameSpace1.MyClass.";
        }
    }
}

namespace NameSpace2
{
    class MyClass<T>
    {
        public override string ToString()
        {
            return "You are in NameSpace2.MyClass.";
        }
    }
}

namespace NameSpace3
{
    class MainClass
    {
        static void Main()
        {
            var instance1 = new AliasToMyClass();
            Console.WriteLine(instance1);

            var instance2 = new UsingAlias();
            Console.WriteLine(instance2);
        }
    }
}
// Output:
//    You are in NameSpace1.MyClass.
//    You are in NameSpace2.MyClass.

Começando no C# 12, você pode criar aliases para tipos que eram restritos, incluindo tipos de tupla, tipos de ponteiro e outros tipos não seguros. Para saber mais sobre as regras atualizadas, confira a especificação de recursos.

Membro de alias qualificado

O qualificador :: de alias de namespace fornece acesso explícito ao namespace global ou a outros aliases de uso potencialmente ocultos por outras entidades.

O global:: garante que a pesquisa de namespace para o namespace após o :: token seja relativa ao namespace global. Caso contrário, o token deve ser resolvido para um alias using e o token após o :: deve ser resolvido para um tipo nesse namespace com alias. O exemplo a seguir mostra os dois formulários:

using S = System.Net.Sockets;

class A
{
    public static int x;
}

class C
{
    public void F(int A, object S)
    {
        // Use global::A.x instead of A.x
        global::A.x += A;

        // Using ::, S must resolve to a namespace alias:
        S::Socket s = S as S::Socket;

        // In this form, if S were a class, it would be a compile-time error:
        S.Socket s1 = S as S.Socket;
    }
}

Especificação da linguagem C#

Para obter mais informações, consulte Diretivas using na Especificação da Linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.

Para obter mais informações sobre o modificador global using, confira a especificação de recurso global using – C# 10.

Confira também