Condividi tramite


La direttiva using

La direttiva using consente di usare i tipi definiti in uno spazio dei nomi senza specificare lo spazio dei nomi completo di tale tipo. Nella forma di base, la direttiva using importa tutti i tipi da un singolo spazio dei nomi, come illustrato nell'esempio seguente:

using System.Text;

È possibile applicare due modificatori a una direttiva using:

  • Il modificatore global ha lo stesso effetto dell'aggiunta della stessa direttiva using a ogni file di origine nel progetto. Questo modificatore è stato introdotto in C# 10.
  • Il modificatore static importa i membri static e i tipi annidati da un singolo tipo anziché importare tutti i tipi in uno spazio dei nomi.

È possibile combinare entrambi i modificatori per importare i membri statici da un tipo a tutti i file di origine del progetto.

È anche possibile creare un alias per uno spazio dei nomi o un tipo con una direttiva alias using.

using Project = PC.MyCompany.Project;

È possibile usare il modificatore global in una direttiva alias using.

Nota

La parola chiave using viene usata anche per creare usingistruzioni, che garantiscono che gli oggetti IDisposable, ad esempio file e tipi di carattere, vengano gestiti correttamente. Per altre informazioni sull'usingistruzione, vedere usingistruzione.

L'ambito di una direttiva using senza il modificatore global è il file in cui compare.

La global using direttiva deve essere visualizzata prima di tutte le dichiarazioni di spazio dei nomi e tipi. Tutte le direttive using globali devono essere visualizzate in un file di origine prima di qualsiasi direttiva non globale using .

Possono essere visualizzate altre using direttive:

  • All'inizio del file del codice sorgente, prima di eventuali dichiarazioni di spazio dei nomi o tipo.
  • In qualsiasi spazio dei nomi con ambito bloccato, ma prima di qualsiasi spazio dei nomi o tipi dichiarati in tale spazio dei nomi.

In caso contrario, viene generato un errore del compilatore.

Creare una direttiva using per usare i tipi in uno spazio dei nomi senza dover specificare tale spazio dei nomi. Una direttiva using non consente di accedere ad alcuno spazio dei nomi annidato nello spazio dei nomi specificato. Gli spazi dei nomi sono disponibili in due categorie: definiti dall'utente e definiti dal sistema. Gli spazi dei nomi definiti dall'utente vengono definiti nel codice. Per un elenco di spazi dei nomi definiti dal sistema, vedere Browser API .NET.

Modificatore global

L'aggiunta del modificatore global a una direttiva using significa che la direttiva using viene applicata a tutti i file nella compilazione (in genere un progetto). La direttiva global using è stata aggiunta in C# 10. La relativa sintassi è la seguente:

global using <fully-qualified-namespace>;

Dove spazio dei nomi completo è il nome completo dello spazio dei nomi a cui è possibile fare riferimento i tipi senza specificare lo spazio dei nomi.

Una direttiva global using può comparire all'inizio di qualsiasi file di codice sorgente. Tutte le direttive global using in un singolo file devono comparire prima di:

  • Tutte le direttive using senza il modificatore global.
  • Tutte le dichiarazioni di spazio dei nomi e tipo nel file.

È possibile aggiungere global using direttive a qualsiasi file di origine. In genere, è necessario mantenerli in un'unica posizione. L'ordine delle direttive global using non è rilevante, sia in un singolo file che tra più file.

Il global modificatore può essere combinato con il static modificatore. Il global modificatore può essere applicato a una direttiva using alias. In entrambi i casi, l'ambito della direttiva corrisponde a tutti i file nella compilazione corrente. Nell'esempio seguente viene abilitato l'uso di tutti i metodi dichiarati in System.Math in tutti i file del progetto:

global using static System.Math;

È anche possibile includere uno spazio dei nomi a livello globale aggiungendo un elemento <Using> al file di progetto, ad esempio <Using Include="My.Awesome.Namespace" />. Per altre informazioni, vedere Elemento <Using>.

Gli analizzatori generano la diagnostica se si duplicano global direttive using in posizioni diverse. Questi stessi analizzatori informano inoltre se si aggiunge una using direttiva per uno spazio dei nomi o un tipo a cui fa già riferimento una global direttiva using. Potrebbe risultare più semplice gestire global gli utilizzi mantenendoli insieme in un unico file del progetto.

Importante

I modelli C# per .NET 6 usano istruzioni di primo livello. L'applicazione potrebbe non corrispondere al codice in questo articolo, se è già stato eseguito l'aggiornamento a .NET 6. Per altre informazioni, vedere l'articolo sui nuovi modelli C# per generare istruzioni di primo livello

.NET 6 SDK aggiunge anche un set di direttive global using implicite per i progetti che usano gli SDK seguenti:

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

Queste direttive global using implicite includono gli spazi dei nomi più comuni per il tipo di progetto.

Per altre informazioni, vedere l'articolo sulle direttive implicite using

Modificatore static

La direttiva using static consente di assegnare un nome a un tipo i cui membri statici e tipi annidati sono accessibili senza specificare un nome di tipo. La relativa sintassi è la seguente:

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

<fully-qualified-type-name> è il nome del tipo per cui è possibile fare riferimento ai membri statici e ai tipi annidati senza specificare un nome di tipo. Se non si specifica un nome di tipo completo (il nome completo dello spazio dei nomi con il nome del tipo), C# genera l'errore del compilatore CS0246: "Impossibile trovare il nome del tipo o dello spazio dei nomi 'type/namespace' (probabilmente manca una direttiva using o un riferimento a un assembly)".

La direttiva using static si applica a qualsiasi tipo che includa membri statici (o tipi nidificati), anche qualora siano presenti membri di istanza. Tuttavia, i membri di istanza possono essere chiamati solo tramite l'istanza del tipo.

È possibile accedere ai membri statici di un tipo senza dover qualificare l'accesso con il nome del tipo:

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

Quando si chiama un membro statico si fornisce in genere il nome del tipo e il nome del membro. Immettere ripetutamente lo stesso nome di tipo per chiamare i membri del tipo può generare codice troppo dettagliato e incomprensibile. Ad esempio, la seguente definizione di una classe Circle fa riferimento a molti membri della 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); }
   }
}

Eliminando la necessità di fare riferimento in modo esplicito alla classe Math ogni volta che si fa riferimento a un membro, la direttiva using static genera codice più chiaro:

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 solo i membri statici accessibili e i tipi annidati dichiarati nel tipo specificato. I membri ereditati non vengono importati. È possibile eseguire l'importazione da qualsiasi tipo denominato con una direttiva using static, inclusi i moduli Visual Basic. Se nei metadati vengono visualizzate funzioni di primo livello F# come membri statici di un tipo denominato il cui nome è un identificatore C# valido, le funzioni F# possono essere importate.

using static crea metodi di estensione dichiarati nel tipo specificato disponibile per la ricerca del metodo di estensione. Tuttavia, i nomi dei metodi di estensione non vengono importati nell'ambito del riferimento non qualificato nel codice.

I metodi con lo stesso nome importati da tipi diversi tramite direttive using static diverse nella stessa unità di compilazione o nello stesso spazio dei nomi costituiscono un gruppo di metodi. La risoluzione dell'overload in questi gruppi di metodi segue le normali regole C#.

L'esempio seguente usa la direttiva using static per rendere i membri statici della classe Console, Math e String disponibili senza dover specificare il nome del 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

Nell'esempio la using static direttiva può essere applicata anche al Double tipo . L'aggiunta di tale direttiva consente di chiamare il metodo TryParse(String, Double) senza specificare un nome di tipo. Tuttavia, l'uso di TryParse senza un nome di tipo crea codice meno leggibile, poiché diventa necessario controllare le direttive using static per determinare quale metodo TryParse del tipo numerico viene chiamato.

using static si applica anche ai tipi enum. Aggiungendo using static con l'enumerazione, non è più necessario che il tipo usi i membri dell'enumerazione.

using static Color;

enum Color
{
    Red,
    Green,
    Blue
}

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

Alias using

Creare una direttiva alias using per semplificare la qualifica di un identificatore in uno spazio dei nomi o un tipo. In una direttiva using è necessario usare lo spazio dei nomi o il tipo completo indipendentemente dalle direttive using che la precedono. Non è possibile usare alcun alias using nella dichiarazione di una direttiva using. Ad esempio, il codice seguente genera un errore del compilatore:

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

Nell'esempio seguente viene illustrato come definire e usare un alias using per uno spazio dei nomi.

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 { }
        }
    }
}

Una direttiva alias using non può contenere un tipo generico aperto sul lato destro. Ad esempio, non è possibile creare un alias using per List<T>, ma è possibile crearne uno per List<int>.

Nell'esempio seguente viene illustrato come definire una direttiva using e un alias using per una 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.

A partire da C# 12, è possibile creare alias per i tipi precedentemente con restrizioni, inclusi i tipi tupla, i tipi puntatore e altri tipi non sicuri. Per altre informazioni sulle regole aggiornate, vedere la specifica delle funzionalità.

Membro alias qualificato

Il qualificatore alias dello spazio dei nomi fornisce :: l'accesso esplicito allo spazio dei nomi globale o ad altri alias potenzialmente nascosti da altre entità.

global:: garantisce che la ricerca dello spazio dei nomi per lo spazio dei nomi che segue il :: token sia relativa allo spazio dei nomi globale. In caso contrario, il token deve essere risolto in un alias usando e il token che segue :: deve essere risolto in un tipo nello spazio dei nomi con alias. L'esempio seguente mostra entrambi i moduli:

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;
    }
}

Specifiche del linguaggio C#

Per altre informazioni, vedere Direttive using in Specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Per altre informazioni sul modificatore global using, vedere la specifica della funzionalità global using - C# 10.

Vedi anche