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 in 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 istruzioni using, che garantiscono che gli oggetti IDisposable, ad esempio file e tipi di carattere, vengano gestiti correttamente. Per altre informazioni sull'istruzione using, vedere Istruzione using.

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

La direttiva using può essere visualizzata:

  • All'inizio del file del codice sorgente, prima di eventuali dichiarazioni di spazio dei nomi o tipo.
  • In qualsiasi spazio dei nomi, ma prima di qualsiasi spazio dei nomi o tipo dichiarato in tale spazio dei nomi, a meno che non venga usato il modificatore global, nel qual caso la direttiva deve comparire prima di tutte le dichiarazioni di spazio dei nomi e tipo.

In caso contrario, viene generato l'errore del compilatore CS1529.

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 fully-qualified-namespace è il nome completo dello spazio dei nomi dei tipi a cui è possibile fare riferimento 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 direttive global using a qualsiasi file di origine. In genere, è consigliabile mantenerle in un'unica posizione. L'ordine delle direttive global using non è rilevante, sia in un singolo file che tra più file.

Il modificatore global può essere combinato con il modificatore static. Il modificatore global può essere applicato a una direttiva alias using. 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>.

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 impliciteglobal using 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 direttiva using static può anche essere stata applicata al tipo Double. 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à.

Come usare lo spazio dei nomi My di Visual Basic

Lo spazio dei nomi Microsoft.VisualBasic.MyServices (My in Visual Basic) consente di accedere in modo semplice e intuitivo a numerose classi .NET, permettendo di scrivere codice che interagisce con il computer, l'applicazione, le impostazioni, le risorse e così via. Anche se originariamente progettato per l'uso con Visual Basic, lo spazio dei nomi MyServices può essere usato nelle applicazioni C#.

Per altre informazioni sull'uso dello spazio dei nomi MyServices da Visual Basic, vedere Development with My (Sviluppo con My).

È necessario aggiungere un riferimento all'assembly Microsoft.VisualBasic.dll nel progetto. Non tutte le classi incluse nello spazio dei nomi MyServices possono essere chiamate da un'applicazione C#. La classe FileSystemProxy, ad esempio, non è compatibile. In questo caso specifico è possibile usare i metodi statici inclusi in FileSystem e contenuti anche nel file VisualBasic.dll. Ecco ad esempio come usare uno di questi metodi per duplicare una directory:

// Duplicate a directory
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
    @"C:\original_directory",
    @"C:\copy_of_original_directory");

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