Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Sugestão
Novo no desenvolvimento de software? Começa primeiro pelos tutoriais para começar . Introduzem namespaces e using diretivas à medida que escreves os teus primeiros programas.
Experiente noutra língua? Os namespaces em C# funcionam de forma semelhante a pacotes em Java ou módulos em Python. Passa rapidamente até à sintaxe que precisas.
As declarações de namespace e diretivas using são características do idioma relacionadas. Uma declaração de namespace coloca os seus tipos numa estrutura organizada. Um espaço de nomes agrupa tipos relacionados e impede colisões de nomeação. Uma using diretiva permite que o seu programa consuma esses tipos pelos seus nomes simples. Não tens de soletrar o caminho completo do namespace em cada uso.
Já usou namespaces em todos os programas de C# que escreveu. Cada tipo .NET pertence a um namespace, e cada using diretiva no topo de um ficheiro faz referência a um. Por exemplo, Console e Math pertencem ao System espaço de nomes, pelo que os seus nomes totalmente qualificados são System.Console e System.Math. Tipos de coleção como List<T> e Dictionary<TKey, TValue> pertencem a System.Collections.Generic. Uma única using diretiva para qualquer um destes espaços de nomes permite-lhe referir-se a todos os seus tipos pelos seus nomes simples. Escreves List<T> em vez de System.Collections.Generic.List<T> em todo o lado onde o usas.
Este artigo fornece mais contexto sobre como funcionam os namespaces e using as diretivas, e mostra exemplos de padrões que já encontraste nas bibliotecas .NET.
Um namespace contém tipos. Cada tipo .NET pertence a um namespace. Por exemplo, considere System.Threading.Tasks.Task: o tipo Task pertence ao System.Threading.Tasks namespace.
É boa prática agrupar tipos relacionados ou semelhantes no mesmo espaço de nomes, e é isso que o .NET faz com os tipos que fornece. O System.Collections.Generic espaço de nomes contém tipos relacionados com coleções e o System.IO espaço de nomes contém tipos relacionados com ficheiros de leitura e escrita, diretórios e dados. O System namespace contém tipos fundamentais como Math, DateTime, e Console.
O exemplo seguinte mostra como os namespaces funcionam em conjunto com using diretivas num ficheiro C# típico:
using System;
using System.Globalization;
namespace MyApp.Services;
class Greeter
{
public string Greet(string name)
{
var culture = CultureInfo.CurrentCulture;
return $"Hello, {name}! Culture: {culture.Name}";
}
}
No exemplo anterior, a using diretiva significa que pode usar o System.Globalization.CultureInfo pelo nome CultureInfo sem especificar o nome completo de System.Globalization.CultureInfo. A namespace diretiva declara que a Greeter classe faz parte do MyApp.Services namespace. O seu nome totalmente qualificado é MyApp.Services.Greeter.
Declarações de espaços de nomes
Uma declaração de namespace atribui os seus tipos a um grupo nomeado. Cada tipo que escreves deve pertencer a um namespace. O nome do namespace normalmente espelha a estrutura de pastas do seu projeto. Por exemplo, os tipos numa Services/Payments pasta frequentemente pertencem ao MyApp.Services.Payments namespace.
Os namespaces usam o . operador para expressar hierarquia, como System.Collections.Generic. Os nomes dos espaços de nomes devem ser nomes válidos de identificadores C#.
Namespaces definidos por arquivo
Use a sintaxe de escopo de ficheiro quando todos os tipos num ficheiro pertencem ao mesmo espaço de nomes. Adicione um ponto e vírgula após a declaração do namespace, e aplica-se a todo o ficheiro. Não precisas de chaves extras nem indentação:
namespace MyApp.Models;
class Customer
{
public required string Name { get; init; }
public string? Email { get; init; }
public override string ToString() => $"{Name} ({Email ?? "no email"})";
}
Os namespaces com escopo de ficheiros reduzem o aninhamento e tornam os ficheiros mais fáceis de ler. Só podes ter uma declaração de namespace com âmbito de ficheiro por ficheiro.
Sugestão
Use namespaces delimitados por ficheiro em código novo. A maioria dos templates e analisadores de código .NET recomenda este estilo.
Espaços de nomes restritos a blocos
Use sintaxe com escopo de blocos quando precisar de declarar mais do que um namespace no mesmo ficheiro. Este estilo adiciona um nível adicional de indentação.
Importante
É raro declarar mais do que um namespace no mesmo ficheiro. O cenário mais comum é usar namespaces com escopo ao nível do ficheiro.
O snippet seguinte é um exemplo de namespace com escopo de blocos :
namespace MyApp.Models
{
class Product
{
public required string Name { get; init; }
public decimal Price { get; init; }
public override string ToString() => $"{Name}: {Price:C}";
}
}
Utilização de diretivas
Sem uma diretiva using, tem de referir cada tipo pelo seu nome totalmente qualificado, o caminho completo do espaço de nomes seguido do nome do tipo. Este estilo é prolixo, repetitivo e mais difícil de ler, especialmente quando um ficheiro utiliza muitos tipos do mesmo espaço de nomes:
static void ShowFullyQualified()
{
// Without a using directive, use the fully qualified name:
System.Console.WriteLine("Hello from fully qualified name!");
}
Uma using diretiva no topo de um ficheiro importa um namespace para que possas usar os seus tipos pelos seus nomes simples. O excerto seguinte mostra o uso de tipos mais curto após essa importação, o que mantém as referências ao longo do ficheiro mais curtas e fáceis de ler:
static void ShowShortName()
{
// With 'using System;' (or implicit usings enabled), use the short name:
Console.WriteLine("Hello from short name!");
}
Para mais informações, consulte a using diretiva.
Diretivas globais de uso
Uma diretiva aplica-se apenas ao ficheiro onde using aparece. Em vez de repetir as mesmas using diretivas em todos os ficheiros, usa diretivas globais , que te permitem declará-las uma vez para todo o teu projeto. Coloca-as em qualquer ficheiro. Muitas equipas criam um ficheiro dedicado GlobalUsings.cs :
global using System.Text;
global using System.Text.Json;
Após declarar um uso global, todos os ficheiros do projeto podem referir-se a tipos desse namespace pelos seus nomes simples sem uma diretiva adicional using . As utilizações globais removem a repetição entre ficheiros, reduzem o bloco using no topo de cada ficheiro e centralizam a política de namespace para o projeto.
Utilizações implícitas
Para os namespaces mais comuns, não tens de escrever quaisquer using diretivas. O SDK .NET gera automaticamente globais usando diretivas baseadas no tipo de projeto. Ative os usos implícitos definindo <ImplicitUsings>enable</ImplicitUsings> no ficheiro do projeto. Por exemplo, um projeto de aplicativo de console importa automaticamente System, System.Collections.Generic, System.IO, System.Linq, System.Threading e System.Threading.Tasks. Os novos projetos que cria com dotnet new ativam ImplicitUsings por predefinição. Novos ficheiros começam limpos, sem diretivas padrão using para tipos do dia a dia como Console, List<T>, ou Task.
Para mais informações, veja Implícito usando diretivas.
Note
Os outros exemplos de código neste artigo, e a maioria dos exemplos em toda a documentação .NET, assumem que as utilizações implícitas (ou as utilizações globais equivalentes para o tipo de projeto) estão ativadas. É por isso que não vês a diretiva using System; nem diretivas semelhantes no topo de cada excerto, mesmo que o código use tipos como Console ou List<T> pelos respetivos nomes simples.
Estática usando diretivas
Uma diretiva importa os membros estáticos de um tipo para que possa chamá-los sem o prefixo static using do nome do tipo:
using static System.Math;
namespace MyApp.Utilities;
class CircleCalculator
{
public static double CalculateArea(double radius) => PI * Pow(radius, 2);
public static double CalculateCircumference(double radius) => 2 * PI * radius;
}
Usos estáticos funcionam bem para classes utilitárias como Math e Console que chamas frequentemente.
Aliases de tipos e namespaces
Um using alias cria um nome abreviado para um tipo ou namespace. Os pseudónimos são úteis para tipos genéricos longos, resolução de conflitos de nomes e melhoria da legibilidade:
using CustomerList = System.Collections.Generic.List<MyApp.Models.Customer>;
namespace MyApp.Services;
class CustomerService
{
public CustomerList GetTopCustomers()
{
CustomerList customers = [new() { Name = "Alice" }, new() { Name = "Bob" }];
return customers;
}
}
A partir de C# 12, podes usar qualquer tipo de alias, incluindo tuplas e tipos de ponteiros:
using Point = (double X, double Y);
namespace MyApp.Geometry;
class Shape
{
public static double Distance(Point a, Point b)
{
var dx = a.X - b.X;
var dy = a.Y - b.Y;
return Math.Sqrt(dx * dx + dy * dy);
}
}
Para cenários mais avançados onde dois assemblies definem o mesmo nome de tipo totalmente qualificado, use alias externo para desambiguar entre eles.