Espacios de nombres y directivas de uso

Sugerencia

¿No está familiarizado con el desarrollo de software? Comience primero con los tutoriales de introducción . Introducen espacios de nombres y using directivas mientras escribes tus primeros programas.

¿Competente en otro idioma? Los espacios de nombres de C# funcionan de forma similar a los paquetes de Java o módulos de Python. Avance rápidamente a la sintaxis que necesita.

Las declaraciones de espacio de nombres y las directivas using son características de lenguaje relacionadas. Una declaración de espacio de nombres coloca los tipos en una estructura organizada. Un espacio de nombres agrupa los tipos relacionados y evita colisiones de nomenclatura. Una using directiva permite que tu programa consuma esos tipos por sus nombres simples. No tiene que escribir la ruta completa del espacio de nombres en cada uso.

Ya ha usado espacios de nombres en todos los programas de C# que ha escrito. Cada tipo de .NET pertenece a un espacio de nombres y cada using directiva de la parte superior de un archivo hace referencia a uno. Por ejemplo, Console y Math pertenecen al System espacio de nombres, por lo que sus nombres completos son System.Console y System.Math. Tipos de colección como List<T> y Dictionary<TKey, TValue> pertenecen a System.Collections.Generic. Una sola using directiva para cualquiera de estos espacios de nombres le permite hacer referencia a todos sus tipos por sus nombres simples. Tú escribes List<T> en lugar de System.Collections.Generic.List<T> cada vez que lo uses.

En este artículo se proporciona más información sobre cómo funcionan los espacios de nombres y using las directivas, y se muestran ejemplos de patrones que ya ha encontrado en las bibliotecas de .NET.

Un espacio de nombres contiene tipos. Cada tipo de .NET pertenece a un espacio de nombres. Por ejemplo, considere System.Threading.Tasks.Task: el tipo Task pertenece al System.Threading.Tasks espacio de nombres .

Se recomienda agrupar tipos relacionados o similares en el mismo espacio de nombres y eso es lo que hace .NET con los tipos que proporciona. El System.Collections.Generic espacio de nombres contiene tipos relacionados con la colección y el System.IO espacio de nombres contiene tipos relacionados con la lectura y escritura de archivos, directorios y datos. El System espacio de nombres contiene tipos fundamentales como Math, DateTimey Console.

En el ejemplo siguiente se muestra cómo funcionan los namespaces junto con las directivas using en un archivo de 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}";
    }
}

En el ejemplo anterior, la using directiva significa que puede usar System.Globalization.CultureInfo por el nombre CultureInfo sin especificar el nombre completo de System.Globalization.CultureInfo. La namespace directiva declara que la Greeter clase forma parte del MyApp.Services espacio de nombres . Su nombre completo es MyApp.Services.Greeter.

Declaraciones de espacio de nombres

Una declaración de espacio de nombres asigna los tipos a un grupo con nombre. Cada tipo que escribas debe pertenecer a un espacio de nombres. El nombre del espacio de nombres normalmente refleja la estructura de carpetas del proyecto. Por ejemplo, los tipos de una Services/Payments carpeta suelen pertenecer al MyApp.Services.Payments espacio de nombres .

Los espacios de nombres usan el . operador para expresar la jerarquía, como System.Collections.Generic. Los nombres de espacio de nombres deben ser nombres de identificador de C# válidos.

Espacios de nombres con ámbito de archivo

Usa la sintaxis con ámbito de archivo cuando todos los tipos de un archivo pertenecen al mismo espacio de nombres. Agregue un punto y coma después de la declaración de espacio de nombres, y este se aplicará a todo el archivo. No necesita llaves adicionales ni sangría:

namespace MyApp.Models;

class Customer
{
    public required string Name { get; init; }
    public string? Email { get; init; }

    public override string ToString() => $"{Name} ({Email ?? "no email"})";
}

Los espacios de nombres a nivel de archivo reducen el anidamiento y hacen que los archivos sean más fáciles de leer. Solo puede tener una declaración de espacio de nombres limitado a un archivo por cada archivo.

Sugerencia

Utiliza espacios de nombres con ámbito de archivo en el nuevo código. La mayoría de las plantillas de .NET y los analizadores de código recomiendan este estilo.

Espacios de nombres con ámbito de bloque

Utilice la sintaxis con ámbito de bloque cuando necesites declarar más de un espacio de nombres en el mismo archivo. Este estilo agrega un nivel adicional de sangría.

Importante

Es raro declarar más de un espacio de nombres en el mismo archivo. El escenario más común es usar espacios de nombres limitados al archivo.

El siguiente fragmento de código es un ejemplo de un espacio de nombres con ámbito de bloque:

namespace MyApp.Models
{
    class Product
    {
        public required string Name { get; init; }
        public decimal Price { get; init; }

        public override string ToString() => $"{Name}: {Price:C}";
    }
}

Directivas de Uso

Sin una directiva using, debe referirse a cada tipo por su nombre completo, la ruta completa del espacio de nombres más el nombre del tipo. Este estilo es detallado, repetitivo y difícil de leer, especialmente cuando un archivo usa muchos tipos del mismo espacio de nombres:

static void ShowFullyQualified()
{
    // Without a using directive, use the fully qualified name:
    System.Console.WriteLine("Hello from fully qualified name!");
}

La directiva using al principio de un archivo importa un espacio de nombres para poder usar sus tipos por su nombre simple. En el siguiente fragmento de código se muestra el uso del tipo abreviado tras esa importación, lo que hace que las referencias en todo el archivo sean más cortas y fáciles de leer:

static void ShowShortName()
{
    // With 'using System;' (or implicit usings enabled), use the short name:
    Console.WriteLine("Hello from short name!");
}

Para obtener más información, consulte la using directiva .

Directivas globales de 'using'

Una using directiva solo se aplica al archivo en el que aparece. En lugar de repetir las mismas directivas using en todos los archivos, use directivas global using, que le permiten declararlas una sola vez en todo el proyecto. Colóquelos en cualquier archivo. Muchos equipos crean un archivo dedicado GlobalUsings.cs :

global using System.Text;
global using System.Text.Json;

Después de declarar un uso global, todos los archivos del proyecto pueden hacer referencia a tipos de ese espacio de nombres por sus nombres simples sin una directiva adicional using . Los usos globales quitan la repetición entre archivos, reducen el using bloque en la parte superior de cada archivo y centralizan la directiva de espacio de nombres para el proyecto.

Usos implícitos

Para los espacios de nombres más comunes, no es necesario escribir ninguna using directiva en absoluto. El SDK de .NET genera automáticamente directivas de uso globales basadas en el tipo de proyecto. Habilite los usos implícitos estableciendo <ImplicitUsings>enable</ImplicitUsings> en el archivo del proyecto. Por ejemplo, un proyecto de aplicación de consola importa System, System.Collections.Generic, System.IO, System.Linq, System.Threading y System.Threading.Tasks automáticamente. Los nuevos proyectos que crees con dotnet new habilitan ImplicitUsings de forma predeterminada. Los archivos nuevos empiezan limpios, sin directivas predefinidas using para tipos cotidianos como Console, List<T> o Task.

Para obtener más información, consulte Directivas using implícitas.

Note

Los otros ejemplos de código de este artículo, y la mayoría de los ejemplos de los documentos de .NET, asumen que se habilitan los usos implícitos (o los usos globales equivalentes para el tipo de proyecto). Por eso no ve using System; y directivas similares en la parte superior de cada fragmento de código, aunque el código use tipos como Console o List<T> por sus nombres simples.

Directivas estáticas de uso

Una static using directiva importa los miembros estáticos de un tipo para que pueda llamarlos sin el prefijo de nombre de 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;
}

Los usos estáticos funcionan bien para las clases de utilidad como Math y Console que se llama con frecuencia.

Alias de tipo y de espacio de nombres

Un using alias crea un nombre abreviado para un tipo o espacio de nombres. Los alias son útiles para tipos genéricos largos, resolver conflictos de nomenclatura y mejorar la legibilidad:

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, se puede crear un alias para cualquier tipo, incluidas las tuplas y los tipos de puntero.

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 escenarios más avanzados en los que dos ensamblados definen el mismo nombre de tipo completo, use extern alias para desambiguar entre ellos.