Cast et conversions de types (guide de programmation C#)Casting and type conversions (C# Programming Guide)

C# étant typé statiquement au moment de la compilation, une fois qu’une variable est déclarée elle ne peut plus être redéclarée et aucune valeur d’un autre type ne peut lui être assignée, sauf si ce type peut être converti de manière implicite au type de la variable.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. Par exemple, string ne peut pas être converti implicitement en int.For example, the string cannot be implicitly converted to int. Après avoir déclaré i comme int, vous ne pouvez donc pas lui assigner la chaîne « Hello », comme l’illustre le code suivant :Therefore, after you declare i as an int, you cannot assign the string "Hello" to it, as the following code shows:

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

Cependant, vous pouvez être amené à copier une valeur dans un paramètre de variable ou de méthode d’un autre type.However, you might sometimes need to copy a value into a variable or method parameter of another type. C’est notamment le cas si vous avez une variable de type entier que vous devez passer à une méthode dont le paramètre est de type double.For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. Il peut également arriver que vous deviez assigner une variable de classe à une variable de type interface.Or you might need to assign a class variable to a variable of an interface type. Les opérations de ce genre sont appelées « conversions de types ».These kinds of operations are called type conversions. En C#, vous pouvez effectuer les conversions suivantes :In C#, you can perform the following kinds of conversions:

  • Conversions implicites : aucune syntaxe spéciale n’est requise, car la conversion est de type sécurisé et les données ne sont pas perdues.Implicit conversions: No special syntax is required because the conversion is type safe and no data will be lost. Citons par exemple les conversions de types intégraux en d’autres plus importants, et les conversions de classes dérivées en classes de base.Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

  • Conversions explicites (casts) : les conversions explicites nécessitent un opérateur de cast.Explicit conversions (casts): Explicit conversions require a cast operator. Un cast est exigé quand les informations peuvent être perdues durant la conversion, ou quand la conversion peut échouer pour d’autres raisons.Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. Exemples classiques : conversion numérique en type qui a moins de précision ou une plus petite plage, et conversion d’une instance de classe de base en classe dérivée.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.

  • Conversions définies par l’utilisateur : les conversions définies par l’utilisateur sont effectuées par des méthodes spéciales que vous pouvez définir pour permettre des conversions explicites ou implicites entre des types personnalisés qui n’ont pas de relation classe de base/classe dérivée.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. Pour plus d’informations, consultez Opérateurs de conversion définie par l’utilisateur.For more information, see User-defined conversion operators.

  • Conversions avec les classes d’assistance : pour effectuer une conversion entre des types non compatibles, tels que des entiers et des objets System.DateTime ou des chaînes hexadécimales et des tableaux d’octets, vous pouvez utiliser la classe System.BitConverter, la classe System.Convert et les méthodes Parse des types numériques intégrés, comme 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. Pour plus d'informations, voir Procédure : Convertir un tableau d’octets en int, Guide pratique pour convertir une chaîne en nombre et Guide pratique pour effectuer une conversion entre des chaînes hexadécimales et des types numériques.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.

Conversions implicitesImplicit conversions

Pour les types numériques intégrés, une conversion implicite peut être effectuée quand la valeur à stocker peut tenir dans la variable sans être tronquée ni arrondie.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. Pour les types intégraux, cela signifie que la plage du type de source est un sous-ensemble approprié de la plage du type cible.For integral types, this means the range of the source type is a proper subset of the range for the target type. Par exemple, une variable de type long (entier sur 64 bits) peut stocker n’importe quelle valeur pouvant être stockée par un int (entier sur 32 bits).For example, a variable of type long (64-bit integer) can store any value that an int (32-bit integer) can store. Dans l’exemple suivant, le compilateur convertit implicitement la valeur de num à droite en type long avant de l’assigner à 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;

Pour obtenir la liste complète de toutes les conversions numériques implicites, consultez Tableau des conversions numériques implicites.For a complete list of all implicit numeric conversions, see Implicit Numeric Conversions Table.

Pour les types référence, il existe toujours une conversion implicite entre une classe et l’une de ses interfaces ou classes de base directes ou indirectes.For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. Aucune syntaxe spéciale n’est nécessaire, car une classe dérivée contient toujours tous les membres d’une classe de base.No special syntax is necessary because a derived class always contains all the members of a base class.

Derived d = new Derived();  
Base b = d; // Always OK.  

Conversions explicitesExplicit conversions

Toutefois, si une conversion ne peut pas être réalisée sans risque de perte d’informations, le compilateur exige une conversion explicite, aussi appelée 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 est une façon d’informer explicitement le compilateur que vous prévoyez de faire la conversion et que vous savez qu’une perte de données peut se produire.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. Pour effectuer un cast, spécifiez le type voulu entre parenthèses devant la valeur ou la variable à convertir.To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. Le programme suivant effectue un cast d’un double en int. Le programme ne se compile pas sans le 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

Pour obtenir la liste des conversions numériques explicites autorisées, consultez Tableau des conversions numériques explicites.For a list of the explicit numeric conversions that are allowed, see Explicit Numeric Conversions Table.

Pour les types référence, un cast explicite est exigé si vous devez effectuer une conversion d’un type de base en type dérivé :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;  

Une opération cast entre types référence ne change pas le type au moment de l’exécution de l’objet sous-jacent. Elle change seulement le type de la valeur utilisée comme référence à cet objet.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. Pour plus d’informations, consultez Polymorphisme.For more information, see Polymorphism.

Exceptions de conversion de type au moment de l’exécutionType conversion exceptions at run time

Dans certaines conversions de types référence, le compilateur ne peut pas déterminer si un cast sera valide.In some reference type conversions, the compiler cannot determine whether a cast will be valid. Il est possible qu’une opération cast dont la compilation fonctionne échoue au moment de l’exécution.It is possible for a cast operation that compiles correctly to fail at run time. Comme l’illustre l’exemple suivant, un cast de type qui échoue au moment de l’exécution provoque la levée d’une exception InvalidCastException.As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown.


using System;

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.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // Cause InvalidCastException at run time 
        // because Mammal is not convertible to Reptile.
        Reptile r = (Reptile)a;
    }

}

C# fournit l’opérateur is pour vous permettre de tester la compatibilité avant d’effectuer réellement un cast.C# provides the is operator to enable you to test for compatibility before actually performing a cast. Pour plus d’informations, consultez Guide pratique pour caster de manière sécurisée avec les critères spéciaux, ainsi que les opérateurs is et as.For more information, see How to: safely cast using pattern matching and the as and is operators.

spécification du langage C#C# language specification

Pour plus d’informations, consultez la section Conversions de la spécification du langage C#.For more information, see the Conversions section of the C# language specification.

Voir aussiSee also