Cast e conversioni di tipi (Guida per programmatori C#)Casting and type conversions (C# Programming Guide)

Poiché C# è tipizzato in modo statico in fase di compilazione, dopo la prima dichiarazione, una variabile non può essere dichiarata di nuovo o assegnata a un valore di un altro tipo, a meno che tale tipo non sia convertibile in modo implicito nel tipo della variabile.Because C# is statically-typed at compile time, after a variable is declared, it cannot be declared again or assigned a value of another type unless that type is implicitly convertible to the variable's type. Ad esempio, string non può essere convertito in modo implicito in int.For example, the string cannot be implicitly converted to int. Pertanto, dopo che si dichiara i come int, non è possibile assegnargli la stringa "Hello", come illustrato nel codice seguente:Therefore, after you declare i as an int, you cannot assign the string "Hello" to it, as the following code shows:

int i;

// error CS0029: Cannot implicitly convert type 'string' to 'int'
i = "Hello";

Potrebbe tuttavia essere necessario copiare un valore in un variabile o un parametro di metodo di un altro tipo.However, you might sometimes need to copy a value into a variable or method parameter of another type. Ad esempio, si potrebbe avere una variabile intera da passare a un metodo il cui parametro è tipizzato come double.For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. O potrebbe essere necessario assegnare una variabile di classe a una variabile di un tipo interfaccia.Or you might need to assign a class variable to a variable of an interface type. Questi tipi di operazioni sono detti conversioni di tipi.These kinds of operations are called type conversions. In C#, è possibile eseguire i tipi di conversioni seguenti:In C#, you can perform the following kinds of conversions:

  • Conversioni implicite: non è necessaria alcuna sintassi speciale perché la conversione ha sempre esito positivo e nessun dato andrà perso.Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Gli esempi includono conversioni dai tipi integrali più piccoli ai più grandi e conversioni dalle classi derivate alle classi di base.Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

  • Conversioni esplicite (cast): le conversioni esplicite richiedono un' espressione cast.Explicit conversions (casts): Explicit conversions require a cast expression. L'esecuzione di cast è obbligatoria se si prevede una possibile perdita di informazioni durante la conversione oppure se la conversione non riesce per altri motivi.Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. Alcuni esempi tipici includono la conversione numerica in un tipo con precisione inferiore o con un intervallo più piccolo e la conversione di un'istanza della classe di base in una classe derivata.Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.

  • Conversioni definite dall'utente: le conversioni definite dall'utente vengono eseguite da metodi speciali che possono essere definiti per abilitare conversioni esplicite e implicite tra tipi personalizzati che non hanno una relazione di classe basata su una classe di base.User-defined conversions: User-defined conversions are performed by special methods that you can define to enable explicit and implicit conversions between custom types that do not have a base class–derived class relationship. Per altre informazioni, vedere Operatori di conversione definiti dall'utente.For more information, see User-defined conversion operators.

  • Conversioni con le classi helper: per eseguire la conversione tra tipi non compatibili, ad esempio numeri interi e oggetti System.DateTime oppure tra stringhe esadecimali e matrici di byte, è possibile usare la classe System.BitConverter, la classe System.Convert e i metodi Parse dei tipi numerici predefiniti, ad esempio Int32.Parse.Conversions with helper classes: To convert between non-compatible types, such as integers and System.DateTime objects, or hexadecimal strings and byte arrays, you can use the System.BitConverter class, the System.Convert class, and the Parse methods of the built-in numeric types, such as Int32.Parse. Per ulteriori informazioni, vedere come convertire una matrice di byte in un tipo int, come convertire una stringa in un numeroe come eseguire la conversione tra stringhe esadecimali e tipi numerici.For more information, see How to convert a byte array to an int, How to convert a string to a number, and How to convert between hexadecimal strings and numeric types.

Conversioni impliciteImplicit conversions

Per i tipi numerici predefiniti, è possibile eseguire una conversione implicita quando il valore da archiviare può essere adattato nella variabile senza essere troncato o arrotondato.For built-in numeric types, an implicit conversion can be made when the value to be stored can fit into the variable without being truncated or rounded off. Per i tipi integrali, questo significa che l'intervallo del tipo di origine è un subset appropriato dell'intervallo per il tipo di destinazione.For integral types, this means the range of the source type is a proper subset of the range for the target type. Ad esempio, una variabile di tipo long (integer a 64 bit) può archiviare qualsiasi valore archiviabile da un tipo int (integer a 32 bit).For example, a variable of type long (64-bit integer) can store any value that an int (32-bit integer) can store. Nell'esempio seguente il compilatore converte in modo implicito il valore num a destra di un tipo long prima di assegnarlo a bigNum.In the following example, the compiler implicitly converts the value of num on the right to a type long before assigning it to bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Per un elenco completo di tutte le conversioni numeriche implicite, vedere la sezione conversioni numeriche implicite dell'articolo sulle conversioni numeriche predefinite .For a complete list of all implicit numeric conversions, see the Implicit numeric conversions section of the Built-in numeric conversions article.

Per i tipi di riferimento, è sempre disponibile una conversione implicita da una classe a qualsiasi classe di base diretta o indiretta o interfacce.For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. Poiché una classe derivata contiene sempre tutti i membri di una classe di base, non è necessaria alcuna sintassi speciale.No special syntax is necessary because a derived class always contains all the members of a base class.

Derived d = new Derived();

// Always OK.
Base b = d;

Conversioni espliciteExplicit conversions

Tuttavia, se una conversione non può essere eseguita senza il rischio di perdita di informazioni, il compilatore richiede di eseguire una conversione esplicita, che viene chiamata cast.However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. Un cast è un modo per informare in modo esplicito il compilatore che si intende eseguire la conversione e che si è a conoscenza del fatto che la perdita di dati potrebbe verificarsi oppure il cast potrebbe non riuscire in fase di esecuzione.A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur, or the cast may fail at runtime. Per eseguire un cast, specificare il tipo tra parentesi davanti al valore o alla variabile da convertire.To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. Il programma seguente esegue il cast di un valore Double a un valore int. Il programma non verrà compilato senza il cast.The following program casts a double to an int. The program will not compile without the cast.

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 completo delle conversioni numeriche esplicite supportate, vedere la sezione conversioni numeriche esplicite dell'articolo sulle conversioni numeriche predefinite .For a complete list of supported explicit numeric conversions, see the Explicit numeric conversions section of the Built-in numeric conversions article.

Per i tipi di riferimento, è necessario un cast esplicito se si vuole eseguire la conversione da un tipo di base a un tipo derivato:For reference types, an explicit cast is required if you need to convert from a base type to a derived type:

// 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 di cast tra tipi di riferimento non modifica il tipo in fase di esecuzione dell'oggetto sottostante. Viene modificato solo il tipo del valore usato come riferimento a tale oggetto.A cast operation between reference types does not change the run-time type of the underlying object; it only changes the type of the value that is being used as a reference to that object. Per altre informazioni, vedere Polimorfismo.For more information, see Polymorphism.

Eccezioni nella conversione di tipi in fase di esecuzioneType conversion exceptions at run time

In alcune conversioni di tipi di riferimento, il compilatore non può determinare se un cast è valido.In some reference type conversions, the compiler cannot determine whether a cast will be valid. È possibile che un'operazione di cast compilata correttamente non riesca in fase di esecuzione.It is possible for a cast operation that compiles correctly to fail at run time. Come illustrato nell'esempio seguente, un cast di tipo che non riesce in fase di esecuzione genera un'eccezione InvalidCastException.As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown.

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "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)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

Il Test metodo ha un Animal parametro, quindi il cast esplicito dell'argomento a a un oggetto Reptile costituisce un presupposto pericoloso.The Test method has an Animal parameter, thus explicitly casting the argument a to a Reptile makes a dangerous assumption. È più sicuro non creare presupposti, ma controllare il tipo.It is safer to not make assumptions, but rather check the type. Il linguaggio C# offre l'operatore is che consente di testare la compatibilità prima di eseguire effettivamente un cast.C# provides the is operator to enable you to test for compatibility before actually performing a cast. Per ulteriori informazioni, vedere come eseguire il cast sicuro usando i criteri di ricerca e gli operatori As e is.For more information, see How to safely cast using pattern matching and the as and is operators.

Specifiche del linguaggio C#C# language specification

Per altre informazioni, vedere la sezione Conversioni della specifica del linguaggio C#.For more information, see the Conversions section of the C# language specification.

Vedere ancheSee also