Cast e conversioni di tipi (Guida per programmatori C#)
Poiché il codice C# viene tipizzato in modo statico in fase di compilazione, una variabile dichiarata non può essere nuovamente dichiarata o utilizzata per archiviare valori di un altro tipo a meno che il tipo non sia convertibile nel tipo della variabile. Ad esempio, non esiste alcuna conversione da un intero a una stringa arbitraria. Pertanto, dopo avere dichiarato i come intero, non è possibile assegnare a esso la stringa "Hello", come mostrato nel codice seguente.
int i;
i = "Hello"; // Error: "Cannot implicitly convert type 'string' to 'int'"
Tuttavia, copiare un valore in una variabile o in un parametro di metodo di un altro tipo potrebbe essere talvolta necessario. Ad esempio, è possibile che si disponga di una variabile integer che è necessario passare a un metodo il cui parametro è tipizzato come double oppure che sia necessario assegnare una variabile di classe a una variabile di un tipo di interfaccia. Questi tipi di operazioni sono detti conversioni di tipi. In C#, è possibile eseguire i tipi di conversioni seguenti:
Conversioni implicite: non è richiesta alcuna sintassi speciale perché la conversione è indipendente dai tipi e nessun dato viene perso. Gli esempi includono le conversioni da tipi integrali più piccoli a più grandi e le conversioni da classi derivate a classi di base.
Conversioni esplicite (cast): le conversioni esplicite richiedono un operatore di cast. Il cast è obbligatoria quando le informazioni potrebbero andare perdute durante la conversione o quando la conversione potrebbe non riuscire per altri motivi. Gli esempi tipici includono la conversione numerica in un tipo con meno precisione o un intervallo più piccolo e la conversione di un'istanza di una classe base in una classe derivata.
Conversioni definite dall'utente: le conversioni definite dall'utente vengono eseguite da metodi speciali che è possibile definire per attivare le conversioni esplicite e implicite fra tipi personalizzati privi di relazione classe di base-classe derivata. Per ulteriori informazioni, vedere Operatori di conversione (Guida per programmatori C#).
Conversioni con le classi di supporto: per eseguire la conversione tra tipi non compatibili, ad esempio numeri interi e oggetti System.DateTime o stringhe esadecimali e matrici di byte, è possibile utilizzare la classe System.BitConverter, la classe System.Convert e i metodi Parse dei tipi numerici incorporati, ad esempio Int32.Parse. Per ulteriori informazioni, vedere Procedura: convertire una matrice di byte in un Integer (Guida per programmatori C#), Procedura: convertire una stringa in un Integer (Guida per programmatori C#) e Procedura: eseguire la conversione tra stringhe esadecimali e tipi numerici (Guida per programmatori C#).
Conversioni implicite
Per i tipi numerici incorporati, una conversione implicita può essere eseguita quando il valore da archiviare può essere adattato alla variabile senza essere troncato o arrotondato. Ad esempio, una variabile di tipo long (intero a 8 byte) è in grado di archiviare qualsiasi valore archiviabile in un tipo int (4 byte su un computer a 32 bit). Nell'esempio seguente, il compilatore converte implicitamente il valore a destra in un tipo long prima di assegnarlo a bigNum.
// Implicit conversion. num long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
Per un elenco completo delle conversioni numeriche implicite, vedere Tabella delle conversioni numeriche implicite (Riferimenti per C#).
Per i tipi riferimento, esiste sempre una conversione implicita da una classe a una delle relative classi di base o interfacce dirette o indirette. Non è necessaria alcuna sintassi speciale perché una classe derivata contiene sempre tutti i membri di una classe di base.
Derived d = new Derived();
Base b = d; // Always OK.
Conversioni esplicite
Tuttavia, se una conversione non può essere eseguita senza un rischio di perdita di informazioni, il compilatore richiede che si esegua una conversione esplicita, chiamata cast. Il cast è un modo di informare in modo esplicito il compilatore che si intende eseguire la conversione e che si è consapevoli che potrebbe verificarsi una perdita di dati. Per eseguire un cast, specificare il tipo di destinazione del cast in parentesi davanti al valore o alla variabile da convertire. Il seguente programma esegue il cast di double su int. Se il cast non è presente, il programma non verrà compilato.
class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
System.Console.WriteLine(a);
}
}
// Output: 1234
Per un elenco delle conversioni numeriche esplicite consentite, vedere Tabella delle conversioni numeriche esplicite (Riferimenti per C#).
Per i tipi riferimento, un cast esplicito è richiesto se è necessario eseguire la conversione da un tipo di base a un tipo derivato:
// Create a new derived type.
Giraffe g = new Giraffe();
// Implicit conversion to base type is safe.
Animal a = g;
// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe) a;
Un'operazione cast tra tipi riferimento non modifica il tipo in fase di esecuzione dell'oggetto sottostante, ma modifica solo il tipo del valore utilizzato come riferimento a tale oggetto. Per ulteriori informazioni, vedere Polimorfismo (Guida per programmatori C#).
Eccezioni di conversione di tipi in fase di esecuzione
In alcune conversioni di tipi riferimento, il compilatore non è in grado di determinare se un cast sarà valido. È possibile che un'operazione di cast compilata correttamente non riesca in fase di esecuzione. Come mostrato nell'esempio seguente, un cast di tipo che non riesce in fase di esecuzione provoca la generazione di InvalidCastException.
class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Reptile : Animal { }
class Mammal : Animal { }
class UnSafeCast
{
static void Main()
{
Test(new Mammal());
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
static void Test(Animal a)
{
// Cause InvalidCastException at run time
// because Mammal is not convertible to Reptile.
Reptile r = (Reptile)a;
}
}
Il linguaggio C# fornisce gli operatori is e as per consentire di verificare la compatibilità prima di eseguire un cast. Per ulteriori informazioni, vedere Procedura: eseguire il cast sicuro tramite gli operatori as e is (Guida per programmatori C#).
Specifiche del linguaggio C#
Per ulteriori informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio è la fonte ufficiale per la sintassi e l'utilizzo di C#.
Vedere anche
Attività
Procedura: convertire una stringa in un Integer (Guida per programmatori C#)
Riferimenti
Tipi (Guida per programmatori C#)
Operatore () (Riferimenti per C#)
Operatori di conversione (Guida per programmatori C#)
Concetti
Conversione di tipi generalizzata
Conversione dei tipi esportati
Cronologia delle modifiche
Data |
Cronologia |
Motivo |
---|---|---|
Giugno 2010 |
Rivista la definizione delle conversioni esplicite nell'introduzione. |
Commenti e suggerimenti dei clienti. |