Types (Guide de programmation C#)Types (C# Programming Guide)

Types, variables et valeursTypes, Variables, and Values

C# est un langage fortement typé.C# is a strongly-typed language. Chaque variable et chaque constante ont un type, tout comme chaque expression qui fournit une valeur.Every variable and constant has a type, as does every expression that evaluates to a value. Chaque signature de méthode spécifie un type pour chaque paramètre d’entrée et pour la valeur de retour.Every method signature specifies a type for each input parameter and for the return value. La bibliothèque de classes .NET définit un ensemble de types numériques intégrés, ainsi que des types plus complexes qui représentent un large éventail de constructions logiques, telles que le système de fichiers, les connexions réseau, les collections et tableaux d’objets, et les dates.The .NET class library defines a set of built-in numeric types as well as more complex types that represent a wide variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and dates. Un programme C# classique utilise des types fournis dans la bibliothèque de classes, mais aussi des types définis par l’utilisateur qui modélisent les concepts propres au domaine du problème du programme.A typical C# program uses types from the class library as well as user-defined types that model the concepts that are specific to the program's problem domain.

Un type peut stocker les informations suivantes :The information stored in a type can include the following:

  • Espace de stockage nécessaire pour une variable du type.The storage space that a variable of the type requires.

  • Valeurs minimale et maximale que le type peut représenter.The maximum and minimum values that it can represent.

  • Membres (méthodes, champs, événements, etc.) que le type contient.The members (methods, fields, events, and so on) that it contains.

  • Type de base dont le type est hérité.The base type it inherits from.

  • Emplacement où sera allouée la mémoire pour les variables au moment de l’exécution.The location where the memory for variables will be allocated at run time.

  • Sortes d’opérations autorisées.The kinds of operations that are permitted.

Le compilateur utilise les informations de type pour s’assurer que toutes les opérations qui sont effectuées dans votre code sont de type safe.The compiler uses type information to make sure that all operations that are performed in your code are type safe. Par exemple, si vous déclarez une variable de type int, le compilateur vous permet d’utiliser la variable dans des opérations d’addition et de soustraction.For example, if you declare a variable of type int, the compiler allows you to use the variable in addition and subtraction operations. Si vous essayez d’effectuer ces mêmes opérations avec une variable de type bool, le compilateur génère une erreur, comme illustré dans l’exemple suivant :If you try to perform those same operations on a variable of type bool, the compiler generates an error, as shown in the following example:

int a = 5;             
int b = a + 2; //OK

bool test = true;
  
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

Notes

Développeurs C et C++ : notez que dans C#, bool n’est pas convertible en int.C and C++ developers, notice that in C#, bool is not convertible to int.

Le compilateur incorpore les informations de type dans le fichier exécutable sous forme de métadonnées.The compiler embeds the type information into the executable file as metadata. Le common language runtime (CLR) utilise ces métadonnées au moment de l’exécution pour garantir que le type est sécurisé lorsqu’il alloue et libère de la mémoire.The common language runtime (CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.

Spécification de types dans les déclarations de variableSpecifying Types in Variable Declarations

Lorsque vous déclarez une variable ou une constante dans un programme, vous devez spécifier son type ou utiliser le mot clé var pour permettre au compilateur de déduire le type.When you declare a variable or constant in a program, you must either specify its type or use the var keyword to let the compiler infer the type. L’exemple suivant montre des déclarations de variable qui utilisent des types numériques intégrés et des types complexes définis par l’utilisateur :The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:

// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):
char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
            where item <= limit
            select item;

Les types de paramètres de méthode et de valeurs de retour sont spécifiés dans la signature de méthode.The types of method parameters and return values are specified in the method signature. La signature suivante présente une méthode qui requiert int comme argument d’entrée et retourne une chaîne :The following signature shows a method that requires an int as an input argument and returns a string:

public string GetName(int ID)
{
    if (ID < names.Length)
        return names[ID];
    else
        return String.Empty;
}
private string[] names = { "Spencer", "Sally", "Doug" };

Après qu’une variable est déclarée, elle ne peut pas être déclarée de nouveau avec un nouveau type et elle ne peut pas être définie sur une valeur qui n’est pas compatible avec son type déclaré.After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not compatible with its declared type. Par exemple, vous ne pouvez pas déclarer une variable de type int et lui assigner la valeur booléenne true.For example, you cannot declare an int and then assign it a Boolean value of true. Toutefois, les valeurs peuvent être converties en d’autres types, par exemple, quand elles sont assignées à de nouvelles variables ou passées comme arguments de méthode.However, values can be converted to other types, for example when they are assigned to new variables or passed as method arguments. Une conversion de type qui ne cause pas de perte de données est effectuée automatiquement par le compilateur.A type conversion that does not cause data loss is performed automatically by the compiler. Une conversion susceptible de causer la perte de données exige une variable cast dans le code source.A conversion that might cause data loss requires a cast in the source code.

Pour plus d’informations, consultez Cast et conversions de types.For more information, see Casting and Type Conversions.

Types intégrésBuilt-in Types

C# fournit un jeu standard de types numériques intégrés pour représenter les nombres entiers, les valeurs à virgule flottante, les expressions booléennes, les caractères de texte, les valeurs décimales et d’autres types de données.C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. Il existe également des types string et object intégrés.There are also built-in string and object types. que vous pouvez utiliser dans n’importe quel programme C#.These are available for you to use in any C# program. Pour plus d’informations sur les types intégrés, consultez Tableaux de référence des types intégrés.For more information about the built-in types, see Reference Tables for built-in Types.

Types personnalisésCustom Types

Vous utilisez les constructions struct, classe, interface et enum pour créer vos propres types personnalisés.You use the struct, class, interface, and enum constructs to create your own custom types. La bibliothèque de classes .NET est une collection de types personnalisés fournie par Microsoft que vous pouvez utiliser dans vos propres applications.The .NET class library itself is a collection of custom types provided by Microsoft that you can use in your own applications. Par défaut, les types les plus fréquemment utilisés dans la bibliothèque de classes sont disponibles dans tous les programmes C#.By default, the most frequently used types in the class library are available in any C# program. Les autres types sont disponibles uniquement si vous ajoutez explicitement une référence de projet à l’assembly dans lequel ils sont définis.Others become available only when you explicitly add a project reference to the assembly in which they are defined. Une fois que le compilateur a une référence à l’assembly, vous pouvez déclarer des variables (et des constantes) des types déclarés dans cet assembly dans le code source.After the compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that assembly in source code. Pour plus d’informations, consultez Bibliothèque de classes .NET.For more information, see .NET Class Library.

Système de type communThe Common Type System

Il est important de comprendre deux points fondamentaux à propos du système de type dans le .NET :It is important to understand two fundamental points about the type system in .NET:

  • Il prend en charge le principe d’héritage.It supports the principle of inheritance. Les types peuvent dériver d’autres types, appelés types de base.Types can derive from other types, called base types. Le type dérivé hérite (avec certaines restrictions) des méthodes, des propriétés et des autres membres du type de base.The derived type inherits (with some restrictions) the methods, properties, and other members of the base type. Le type de base peut, à son tour, dériver d’un autre type, auquel cas le type dérivé hérite des membres des deux types de base dans sa hiérarchie d’héritage.The base type can in turn derive from some other type, in which case the derived type inherits the members of both base types in its inheritance hierarchy. Tous les types, notamment les types numériques intégrés comme System.Int32 (mot clé C# : int), dérivent au final d’un seul type de base, qui est System.Object (mot clé C# : object).All types, including built-in numeric types such as System.Int32 (C# keyword: int), derive ultimately from a single base type, which is System.Object (C# keyword: object). Cette hiérarchie de types unifiée est appelée Système de type commun (CTS).This unified type hierarchy is called the Common Type System (CTS). Pour plus d’informations sur l’héritage dans C#, consultez Héritage.For more information about inheritance in C#, see Inheritance.

  • Chaque type du CTS est défini comme type valeur ou type référence.Each type in the CTS is defined as either a value type or a reference type. Cela inclut tous les types personnalisés dans la bibliothèque de classes .NET, ainsi que les types définis par l’utilisateur.This includes all custom types in the .NET class library and also your own user-defined types. Les types que vous définissez à l’aide du mot clé struct sont des types valeur ; tous les types numériques intégrés sont structs.Types that you define by using the struct keyword are value types; all the built-in numeric types are structs. Les types que vous définissez à l’aide du mot clé class sont des types référence.Types that you define by using the class keyword are reference types. Les types référence et les types valeur ont des règles différentes lors de la compilation et un comportement différent au moment de l’exécution.Reference types and value types have different compile-time rules, and different run-time behavior.

L’illustration suivante montre la relation entre les types valeur et les types référence dans le CTS.The following illustration shows the relationship between value types and reference types in the CTS.

L’image suivante montre les types valeur et les types référence dans CTS :The following image shows value types and reference types in the CTS:

Capture d’écran montrant des types valeur et des types référence dans CTS.

Notes

Vous pouvez voir que les types couramment utilisés sont tous organisés dans l’espace de noms System.You can see that the most commonly used types are all organized in the System namespace. Toutefois, l’espace de noms qui contient un type n’a aucune incidence sur le fait qu’il s’agisse d’un type valeur ou d’un type référence.However, the namespace in which a type is contained has no relation to whether it is a value type or reference type.

Types valeurValue Types

Les types valeur dérivent de System.ValueType, qui dérive de System.Object.Value types derive from System.ValueType, which derives from System.Object. Les types qui dérivent de System.ValueType ont un comportement spécial dans le CLR.Types that derive from System.ValueType have special behavior in the CLR. Les variables de type valeur contiennent directement leurs valeurs, ce qui signifie que la mémoire est allouée inline dans le contexte où la variable est déclarée.Value type variables directly contain their values, which means that the memory is allocated inline in whatever context the variable is declared. Aucune allocation des tas ni surcharge de garbage collection distincte n’a lieu pour les variables de type valeur.There is no separate heap allocation or garbage collection overhead for value-type variables.

Il existe deux catégories de types valeur : struct et enum.There are two categories of value types: struct and enum.

Les types numériques intégrés sont des structs et disposent de propriétés et de méthodes auxquelles vous pouvez accéder :The built-in numeric types are structs, and they have properties and methods that you can access:

// Static method on type byte.
byte b = byte.MaxValue;

Mais vous les déclarez et leur affectez des valeurs comme s’ils étaient de simples types non agrégés :But you declare and assign values to them as if they were simple non-aggregate types:

byte num = 0xA;
int i = 5;
char c = 'Z';

Les types valeur sont scellés (sealed), ce qui signifie que par exemple que vous ne pouvez pas dériver un type de System.Int32. Vous ne pouvez pas non plus définir un struct pour qu’il hérite d’une classe ou d’un struct défini par l’utilisateur car un struct peut uniquement hériter de System.ValueType.Value types are sealed, which means, for example, that you cannot derive a type from System.Int32, and you cannot define a struct to inherit from any user-defined class or struct because a struct can only inherit from System.ValueType. Toutefois, un struct peut implémenter une ou plusieurs interfaces.However, a struct can implement one or more interfaces. Vous pouvez effectuer un cast d’un type struct en un type interface qu’il met en œuvre. En conséquence, une opération de boxing encapsule le struct dans un objet de type référence sur le tas managé.You can cast a struct type to any interface type that it implements; this causes a boxing operation to wrap the struct inside a reference type object on the managed heap. Les opérations de boxing se produisent quand vous passez un type valeur à une méthode qui prend un System.Object ou tout type d’interface comme paramètre d’entrée.Boxing operations occur when you pass a value type to a method that takes a System.Object or any interface type as an input parameter. Pour plus d’informations, consultez Conversion boxing et unboxing.For more information, see Boxing and Unboxing.

Vous utilisez le mot clé struct pour créer vos propres types valeur personnalisés.You use the struct keyword to create your own custom value types. En règle générale, un struct est utilisé comme conteneur pour un petit jeu de variables connexes, comme le montre l'exemple suivant :Typically, a struct is used as a container for a small set of related variables, as shown in the following example:

public struct Coords
{
    public int x, y;

    public Coords(int p1, int p2)
    {
        x = p1;
        y = p2;
    }
}

Pour plus d’informations sur les structs, consultez Structs.For more information about structs, see Structs. Pour plus d’informations sur les types valeur dans .NET, consultez Types valeur.For more information about value types in .NET, see Value Types.

L’autre catégorie de types valeur est enum.The other category of value types is enum. Un enum définit un jeu de constantes intégrales nommées.An enum defines a set of named integral constants. Par exemple l’énumération System.IO.FileMode dans la bibliothèque de classes du .NET contient un ensemble d’entiers constants nommés qui spécifient comment un fichier doit être ouvert.For example, the System.IO.FileMode enumeration in the .NET class library contains a set of named constant integers that specify how a file should be opened. Ceci est défini comme indiqué dans l’exemple suivant :It is defined as shown in the following example:

public enum FileMode
{
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,
}

La constante System.IO.FileMode.Create a la valeur 2.The System.IO.FileMode.Create constant has a value of 2. Toutefois, le nom est beaucoup plus explicite pour les êtres humains qui lisent le code source et c’est pourquoi il est préférable d’utiliser des énumérations au lieu de chiffres littéraux constants.However, the name is much more meaningful for humans reading the source code, and for that reason it is better to use enumerations instead of constant literal numbers. Pour plus d'informations, consultez System.IO.FileMode.For more information, see System.IO.FileMode.

Toutes les énumérations héritent de System.Enum, qui hérite de System.ValueType.All enums inherit from System.Enum, which inherits from System.ValueType. Toutes les règles qui s’appliquent aux structs s’appliquent également aux enums.All the rules that apply to structs also apply to enums. Pour plus d’informations sur les enums, consultez Types énumération.For more information about enums, see Enumeration Types.

Types référenceReference Types

Un type qui est défini comme une classe, un délégué, un tableau ou une interface est un type référence.A type that is defined as a class, delegate, array, or interface is a reference type. Au moment de l’exécution, quand vous déclarez une variable de type référence, celle-ci contient la valeur null tant que vous n’avez pas explicitement créé un objet à l’aide de l’opérateur new ou que vous ne lui avez pas assigné un objet créé ailleurs à l’aide de new, comme indiqué dans l’exemple suivant :At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an object by using the new operator, or assign it an object that has been created elsewhere by using new, as shown in the following example:

MyClass mc = new MyClass();
MyClass mc2 = mc;

Une interface doit être initialisée avec un objet de classe qui l’implémente.An interface must be initialized together with a class object that implements it. Si MyClass implémente IMyInterface, vous créez une instance de IMyInterface comme indiqué dans l’exemple suivant :If MyClass implements IMyInterface, you create an instance of IMyInterface as shown in the following example:

IMyInterface iface = new MyClass();

Quand l’objet est créé, la mémoire est allouée sur le tas managé et la variable contient uniquement une référence à l’emplacement de l’objet.When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Les types sur le tas managé entraînent une surcharge quand ils sont alloués et récupérés par la fonctionnalité de gestion automatique de la mémoire du CLR (appelée garbage collection).Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage collection. Toutefois, le garbage collection est également optimisé, et dans la plupart des cas, ne nuit pas aux performances.However, garbage collection is also highly optimized, and in most scenarios it does not create a performance issue. Pour plus d’informations sur le garbage collection, consultez Gestion automatique de la mémoire.For more information about garbage collection, see Automatic Memory Management.

Tous les tableaux sont des types référence, même si leurs éléments sont des types valeur.All arrays are reference types, even if their elements are value types. Les tableaux dérivent implicitement de la classe System.Array, mais vous les déclarez et vous les utilisez avec la syntaxe simplifiée fournie par C#, comme illustré dans l’exemple suivant :Arrays implicitly derive from the System.Array class, but you declare and use them with the simplified syntax that is provided by C#, as shown in the following example:

// Declare and initialize an array of integers.
int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.
int len = nums.Length;

Les types référence prennent en charge l’héritage.Reference types fully support inheritance. Quand vous créez une classe, vous pouvez hériter de toute autre interface ou classe qui n’est pas définie comme sealed, et d’autres classes peuvent hériter de votre classe et substituer vos méthodes virtuelles.When you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes can inherit from your class and override your virtual methods. Pour plus d’informations sur la création de vos propres classes, consultez Classes et structures.For more information about how to create your own classes, see Classes and Structs. Pour plus d’informations sur l’héritage et les méthodes virtuelles, consultez Héritage.For more information about inheritance and virtual methods, see Inheritance.

Types de valeurs littéralesTypes of Literal Values

Dans C#, les valeurs littérales reçoivent un type du compilateur.In C#, literal values receive a type from the compiler. Vous pouvez spécifier la façon dont un littéral numérique doit être typé en ajoutant une lettre à la fin du nombre.You can specify how a numeric literal should be typed by appending a letter to the end of the number. Par exemple, pour spécifier que la valeur 4,56 doit être traitée comme une valeur float, ajoutez « f » ou « F » après le nombre : 4.56f.For example, to specify that the value 4.56 should be treated as a float, append an "f" or "F" after the number: 4.56f. Si aucune lettre n’est ajoutée, le compilateur déduit un type pour le littéral.If no letter is appended, the compiler will infer a type for the literal. Pour plus d’informations sur les types qui peuvent être spécifiés avec une lettre en suffixe, consultez les pages de référence des différents types dans Types valeur.For more information about which types can be specified with letter suffixes, see the reference pages for individual types in Value Types.

Comme les littéraux sont typés et que tous les types dérivent en fin de compte de System.Object, vous pouvez écrire et compiler du code, tel que le suivant :Because literals are typed, and all types derive ultimately from System.Object, you can write and compile code such as the following:

string s = "The answer is " + 5.ToString();
// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();
// Outputs: "System.Int32"
Console.WriteLine(type);

Types génériquesGeneric Types

Un type peut être déclaré avec un ou plusieurs paramètres de type qui servent d’espace réservé pour le type réel (le type concret) que le code client fournit lorsqu’il crée une instance du type.A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the concrete type) that client code will provide when it creates an instance of the type. Ces types sont appelés types génériques.Such types are called generic types. Par exemple, le type .NET System.Collections.Generic.List<T> a un paramètre de type qui, par convention, porte le nom T. Lorsque vous créez une instance du type, vous spécifiez le type des objets contenus dans la liste, par exemple, une chaîne :For example, the .NET type System.Collections.Generic.List<T> has one type parameter that by convention is given the name T. When you create an instance of the type, you specify the type of the objects that the list will contain, for example, string:

List<string> stringList = new List<string>();
stringList.Add("String example");
// compile time error adding a type other than a string:
stringList.Add(4);

L’utilisation du paramètre de type rend possible la réutilisation de la même classe pour contenir tout type d’élément, sans avoir à convertir chaque élément en object.The use of the type parameter makes it possible to reuse the same class to hold any type of element, without having to convert each element to object. Les classes de collections génériques sont appelées collections fortement typées, car le compilateur connaît le type spécifique des éléments de chaque collection et il peut déclencher une erreur au moment de la compilation. C’est le cas, par exemple, si vous essayez d’ajouter un entier à l’objet stringList dans l’exemple précédent.Generic collection classes are called strongly-typed collections because the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for example, you try to add an integer to the stringList object in the previous example. Pour plus d’informations, consultez la page Génériques.For more information, see Generics.

Types implicites, types anonymes et types NullableImplicit Types, Anonymous Types, and Nullable Types

Comme indiqué précédemment, vous pouvez attribuer implicitement un type à une variable locale (mais pas les membres de la classe) à l’aide du mot clé var.As stated previously, you can implicitly type a local variable (but not class members) by using the var keyword. La variable reçoit toujours un type au moment de la compilation, mais le type est fourni par le compilateur.The variable still receives a type at compile time, but the type is provided by the compiler. Pour plus d’informations, consultez Variables locales implicitement typées.For more information, see Implicitly Typed Local Variables.

Dans certains cas, il est difficile de créer un type nommé pour des ensembles simples de valeurs associées que vous ne souhaitez pas stocker ou transférer en dehors des limites de la méthode.In some cases, it is inconvenient to create a named type for simple sets of related values that you do not intend to store or pass outside method boundaries. Vous pouvez créer des types anonymes à cet effet.You can create anonymous types for this purpose. Pour plus d’informations, consultez Types anonymes.For more information, see Anonymous Types.

Les types valeur ordinaires ne peuvent pas avoir la valeur Null.Ordinary value types cannot have a value of null. Toutefois, vous pouvez créer des types valeur Nullable en apposant un ? après le type.However, you can create nullable value types by affixing a ? after the type. Par exemple, int? est un type int qui peut également avoir la valeur null.For example, int? is an int type that can also have the value null. Dans le CTS, les types Nullable sont des instances du type struct générique System.Nullable<T>.In the CTS, nullable types are instances of the generic struct type System.Nullable<T>. Les types Nullable sont particulièrement utiles lorsque vous passez des données vers et à partir de bases de données dans lesquelles les valeurs numériques peuvent être Null.Nullable types are especially useful when you are passing data to and from databases in which numeric values might be null. Pour plus d’informations, consultez Types Nullable.For more information, see Nullable Types.

Pour plus d’informations, consultez les rubriques suivantes :For more information, see the following topics:

Spécification du langage C#C# Language Specification

Pour plus d'informations, voir la spécification du langage C#.For more information, see the C# Language Specification. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.The language specification is the definitive source for C# syntax and usage.

Voir aussiSee also