IntroductionIntroduction

C# (prononcé « C Sharp ») est un langage de programmation simple, moderne, orienté objet et de type sécurisé.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C# a ses racines dans la famille de langages C et sera immédiatement reconnaissable aux programmeurs en C, C++ et Java.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C# est normalisé par ECMA International en tant que le ECMA-334 standard et par la norme ISO/IEC comme le ISO/CEI 23270 standard.C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. Compilateur c# de Microsoft pour le .NET Framework est une implémentation conforme de ces deux normes.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C# est un langage orienté objet, mais C# inclut de plus la prise en charge de la programmation orientée composant.C# is an object-oriented language, but C# further includes support for component-oriented programming. La conception logicielle moderne s’appuie de plus en plus sur les composants logiciels sous la forme de packages de fonctionnalités autonomes et autodescriptifs.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. Point important, ces composants présentent un modèle de programmation avec propriétés, méthodes et événements ; ils ont des attributs qui fournissent des informations déclaratives sur le composant ; et ils intègrent leur propre documentation.Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C# fournit des constructions de langage qui prennent directement en charge ces concepts, rendre c# un langage très naturel permettant de créer et utiliser des composants logiciels.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Plusieurs fonctionnalités de C# participent à la construction d’applications robustes et fiables : Le garbage collection récupère automatiquement la mémoire occupée par les objets inutilisés ; gestion des exceptions offre une approche structurée et extensible pour la détection d’erreur et de récupération ; et le type-safe conception du langage ne permet pas de lire à partir de variables non initialisées, pour indexer des tableaux au-delà de leurs limites, ou réaliser unchecked casts de type.Several C# features aid in the construction of robust and durable applications: Garbage collection automatically reclaims memory occupied by unused objects; exception handling provides a structured and extensible approach to error detection and recovery; and the type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

C# a un système de type unifié.C# has a unified type system. Tous les types C#, y compris les types primitifs tels que int et double, héritent d’un seul type object racine.All C# types, including primitive types such as int and double, inherit from a single root object type. Par conséquent, tous les types partagent un ensemble d’opérations communes, et des valeurs de tous types peuvent être stockées, transmises et exploitées de manière cohérente.Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. En outre, C# prend en charge les types référence et les types valeur définis par l’utilisateur, ce qui permet l’allocation dynamique d’objets, ainsi que le stockage en ligne de structures légères.Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

Pour vous assurer que les bibliothèques et les programmes c# peuvent évoluer au fil du temps de manière compatible, l’accent a été placé sur versioning dans la conception de #.To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. De nombreux langages de programmation n’accordent que peu d’attention à ce problème ; par conséquent, les programmes écrits dans ces langages s’arrêtent plus souvent que nécessaire lors de l’introduction de versions plus récentes des bibliothèques dépendantes.Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. Aspects de C#include de conception qui ont été directement influencés par les considérations relatives à la gestion des versions de la distinct virtual et override modificateurs, les règles de résolution de surcharge de méthode et la prise en charge pour les déclarations de membre d’interface explicite.Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

Le reste de ce chapitre décrit les principales fonctionnalités du langage c#.The rest of this chapter describes the essential features of the C# language. Bien que les chapitres suivants décrivent les règles et les exceptions de manière très détaillée et parfois mathématique, ce chapitre s’efforce de clarté et la concision au détriment d’exhaustivité.Although later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. L’objectif est de fournir au lecteur une introduction au langage qui facilite l’écriture de programmes précoce et la lecture des chapitres.The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters.

Hello WorldHello world

Le programme « Hello, World » est souvent utilisé pour présenter un langage de programmation.The "Hello, World" program is traditionally used to introduce a programming language. Le voici en C# :Here it is in C#:

using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}

Les fichiers sources C# ont généralement l’extension de fichier .cs.C# source files typically have the file extension .cs. En supposant que le programme « Hello, World » est stocké dans le fichier hello.cs, le programme peut être compilé avec le compilateur Microsoft c# à l’aide de la ligne de commandeAssuming that the "Hello, World" program is stored in the file hello.cs, the program can be compiled with the Microsoft C# compiler using the command line

csc hello.cs

ce qui génère un assembly exécutable nommé hello.exe.which produces an executable assembly named hello.exe. La sortie générée par cette application lorsqu’elle est exécutéeThe output produced by this application when it is run is

Hello, World

Le programme « Hello, World » commence par une directive using qui fait référence à l’espace de noms System.The "Hello, World" program starts with a using directive that references the System namespace. Les espaces de noms représentent un moyen hiérarchique d’organiser les bibliothèques et les programmes C#.Namespaces provide a hierarchical means of organizing C# programs and libraries. Les espaces de noms contiennent des types et d’autres espaces de noms ; par exemple, l’espace de noms System contient plusieurs types, notamment la classe Console référencée dans le programme, et d’autres espaces de noms, tels que IO et Collections.Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. Une directive using qui fait référence à un espace de noms donné permet l’utilisation non qualifiée des types membres de cet espace de noms.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. En raison de la directive using, le programme peut utiliser Console.WriteLine comme raccourci pour System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

La classe Hello déclarée par le programme « Hello, World » a un membre unique, la méthode nommée Main.The Hello class declared by the "Hello, World" program has a single member, the method named Main. Le Main méthode est déclarée avec le static modificateur.The Main method is declared with the static modifier. Si les méthodes d’instance peuvent faire référence à une instance d’objet englobante particulière avec le mot clé this, les méthodes statiques fonctionnent sans référence à un objet particulier.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Par convention, une méthode statique nommée Main sert de point d’entrée d’un programme.By convention, a static method named Main serves as the entry point of a program.

La sortie du programme est générée par la méthode WriteLine de la classe Console dans l’espace de noms System.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Cette classe est fournie par les bibliothèques de classes .NET Framework, qui, par défaut, sont référencés automatiquement par le compilateur Microsoft C#.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Notez que c# lui-même n’a pas une bibliothèque d’exécution distinct.Note that C# itself does not have a separate runtime library. Au lieu de cela, le .NET Framework est la bibliothèque runtime du langage c#.Instead, the .NET Framework is the runtime library of C#.

Structure de programmeProgram structure

Les concepts clés d’organisation en C# sont les programmes, espaces de noms, types, membres et assemblys.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. Les programmes C++, comme les programmes C, se composent d'un ou plusieurs fichiers sources.C# programs consist of one or more source files. Les programmes déclarent des types qui contiennent des membres et peuvent être organisés en espaces de noms.Programs declare types, which contain members and can be organized into namespaces. Les classes et les interfaces sont des exemples de types.Classes and interfaces are examples of types. Les champs, méthodes, propriétés et événements sont des exemples de membres.Fields, methods, properties, and events are examples of members. Lorsque les programmes C# sont compilés, ils sont physiquement empaquetés dans des assemblys.When C# programs are compiled, they are physically packaged into assemblies. Assemblys ont généralement l’extension de fichier .exe ou .dll, selon qu’ils implémentent applications ou bibliothèques.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

L’exempleThe example

using System;

namespace Acme.Collections
{
    public class Stack
    {
        Entry top;

        public void Push(object data) {
            top = new Entry(top, data);
        }

        public object Pop() {
            if (top == null) throw new InvalidOperationException();
            object result = top.data;
            top = top.next;
            return result;
        }

        class Entry
        {
            public Entry next;
            public object data;
    
            public Entry(Entry next, object data) {
                this.next = next;
                this.data = data;
            }
        }
    }
}

déclare une classe nommée Stack dans un espace de noms appelé Acme.Collections.declares a class named Stack in a namespace called Acme.Collections. Le nom qualifié complet de cette classe est Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. La classe contient plusieurs membres : un champ nommé top, deux méthodes nommées Push et Pop, et une classe imbriquée nommée Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. La classe Entry contient trois membres en plus : un champ nommé next, un autre nommé data et un constructeur.The Entry class further contains three members: a field named next, a field named data, and a constructor. En supposant que le code source de l’exemple est stocké dans le fichier acme.cs, la ligne de commandeAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

compile l’exemple en tant que bibliothèque (code sans point d’entrée Main) et produit un assembly nommé acme.dll.compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Les assemblys contiennent du code exécutable sous la forme de Intermediate Language instructions (IL) et des informations symboliques sous la forme de métadonnées.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Avant son exécution, le code de langage intermédiaire dans un assembly est automatiquement converti en code spécifique au processeur par le compilateur juste à temps (JIT) du Common Language Runtime .NET.Before it is executed, the IL code in an assembly is automatically converted to processor-specific code by the Just-In-Time (JIT) compiler of .NET Common Language Runtime.

Comme un assembly est une unité de fonctionnalité autodescriptive contenant du code et des métadonnées, les directives #include et les fichiers d’en-tête ne sont pas nécessaires en C#.Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. Les membres et types publics contenus dans un assembly particulier sont disponibles dans un programme C# par simple référence à cet assembly lors de la compilation du programme.The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. Par exemple, ce programme utilise la classe Acme.Collections.Stack à partir de l’assembly acme.dll :For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Test
{
    static void Main() {
        Stack s = new Stack();
        s.Push(1);
        s.Push(10);
        s.Push(100);
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
    }
}

Si le programme est stocké dans le fichier test.cs, lorsque test.cs est compilé, le acme.dll assembly peut être référencé à l’aide du compilateur /r option :If the program is stored in the file test.cs, when test.cs is compiled, the acme.dll assembly can be referenced using the compiler's /r option:

csc /r:acme.dll test.cs

Cela permet de créer un assembly exécutable nommé test.exe, qui, lors de l’exécution, produit la sortie :This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C# permet le stockage du texte source d’un programme dans plusieurs fichiers source.C# permits the source text of a program to be stored in several source files. Lorsqu’un programme C# multifichier est compilé, tous les fichiers source sont traités ensemble et les fichiers source peuvent librement se référencer mutuellement. Sur le plan conceptuel, c’est comme si tous les fichiers source étaient concaténés en un seul fichier volumineux avant d’être traités.When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. Déclarations anticipées ne sont jamais nécessaires en C#, car, à de très rares exceptions près, l’ordre de déclaration n’a pas d’importance.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C# ne limite pas un fichier source à la déclaration d’un seul type public et ne nécessite pas non plus que le nom du fichier source corresponde à un type déclaré dans ce fichier.C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.

Types et variablesTypes and variables

Il existe deux genres de types en C# : les types référence et les types valeur.There are two kinds of types in C#: value types and reference types. Les variables des types valeur contiennent directement leurs données alors que les variables des types référence contiennent des références à leurs données, connues sous le nom d’objets.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. Avec les types référence, deux variables peuvent faire référence au même objet et, par conséquent, les opérations sur une variable peuvent affecter le même objet référencé par l'autre variable.With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Avec les types valeur, les variables possèdent leur propre copie de données, et les opérations sur une variable ne peuvent absolument pas affecter l'autre (sauf pour les variables de paramètre ref et out).With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).

C#de types valeur sont divisés en types simples, types enum, types struct, et types nullable, et C#de types référence sont divisés en types de classes, types d’interfaces, types tableau, et types délégués.C#'s value types are further divided into simple types, enum types, struct types, and nullable types, and C#'s reference types are further divided into class types, interface types, array types, and delegate types.

Le tableau suivant fournit une vue d’ensemble de C#du système de type.The following table provides an overview of C#'s type system.

CatégorieCategory DescriptionDescription
Types de valeurValue types Types simplesSimple types Entier signé : sbyte, short, int, longSigned integral: sbyte, short, int, long
Entier non signé : byte, ushort, uint, ulongUnsigned integral: byte, ushort, uint, ulong
Caractères Unicode : charUnicode characters: char
Virgule flottante IEEE : float, doubleIEEE floating point: float, double
Décimale haute précision :decimalHigh-precision decimal: decimal
Booléen : boolBoolean: bool
Types d'enumEnum types Types définis par l'utilisateur de la forme enum E {...}User-defined types of the form enum E {...}
Types structStruct types Types définis par l'utilisateur de la forme struct S {...}User-defined types of the form struct S {...}
Types NullableNullable types Extensions de tous les autres types de valeurs avec une valeur nullExtensions of all other value types with a null value
Types référenceReference types Types de classesClass types Classe de base fondamentale de tous les autres types : objectUltimate base class of all other types: object
Chaînes Unicode : stringUnicode strings: string
Types définis par l'utilisateur de la forme class C {...}User-defined types of the form class C {...}
Types interfaceInterface types Types définis par l'utilisateur de la forme interface I {...}User-defined types of the form interface I {...}
Types de tableauxArray types Uni et multidimensionnels, par exemple int[] et int[,]Single- and multi-dimensional, for example, int[] and int[,]
Types déléguésDelegate types Les types définis par l’utilisateur du formulaire, par exemple delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Les types intégraux huit prennent en charge les valeurs 8 bits, 16 bits, 32 bits et 64 bits sous forme signée ou non signée.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Les deux flottante types, de points float et double, sont représentés au format les 32 bits simple précision et 64 bits double précision IEEE 754.The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

Le type decimal est un type de données 128 bits adapté aux calculs financiers et monétaires.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C# bool type est utilisé pour représenter des valeurs booléennes, qui peuvent être true ou false.C#'s bool type is used to represent boolean values—values that are either true or false.

Le traitement des caractères et chaînes dans le langage C# utilise l’encodage Unicode.Character and string processing in C# uses Unicode encoding. Le type char représente une unité de code UTF-16, et le type string représente une séquence d’unités de code UTF-16.The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

Le tableau suivant récapitule C#de types numériques.The following table summarizes C#'s numeric types.

CatégorieCategory BitsBits TypeType Plage/précisionRange/Precision
Type intégral signéSigned integral 88 sbyte -128...127-128...127
1616 short -32,768...32,767-32,768...32,767
3232 int -2,147,483,648...2,147,483,647-2,147,483,648...2,147,483,647
6464 long -9,223,372,036,854,775,808...9,223,372,036,854,775,807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Entier non signéUnsigned integral 88 byte 0...2550...255
1616 ushort 0...65,5350...65,535
3232 uint 0...4,294,967,2950...4,294,967,295
6464 ulong 0...18,446,744,073,709,551,6150...18,446,744,073,709,551,615
Virgule flottanteFloating point 3232 float 1,5 × 10 ^ −45 à 3,4 × 10 ^ 38, précision de 7 chiffres1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ −324 à 1,7 × 10 ^ 308, précision de 15 chiffres5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1.0 × 10 ^ −28 à 7,9 × 10 ^ 28, 28 chiffres1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

Les programmes C# utilisent les déclarations de type pour créer de nouveaux types.C# programs use type declarations to create new types. Une déclaration de type spécifie le nom et les membres du nouveau type.A type declaration specifies the name and the members of the new type. Cinq de C#de catégories de types sont définis par l’utilisateur : classe de types, les types struct, les types d’interface, les types enum et les types délégués.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Un type de classe définit une structure de données qui contient les données membres (champs) et des fonctions membres (méthodes, propriétés, etc.).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Les types de classes prennent en charge l’héritage unique et le polymorphisme, des mécanismes par lesquels les classes dérivées peuvent étendre et spécialiser les classes de base.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Un type struct est similaire à un type de classe, car il représente une structure avec des membres de données et des fonctions membres.A struct type is similar to a class type in that it represents a structure with data members and function members. Toutefois, contrairement aux classes, structs sont des types valeur et ne nécessitent pas d’allocation de tas.However, unlike classes, structs are value types and do not require heap allocation. Les types struct ne prennent pas en charge l’héritage spécifié par l’utilisateur, et tous les types struct héritent implicitement du type object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Un type d’interface définit un contrat comme un jeu nommé de membres de la fonction publique.An interface type defines a contract as a named set of public function members. Une classe ou un struct qui implémente une interface doit fournir des implémentations de fonctions membres de l’interface.A class or struct that implements an interface must provide implementations of the interface's function members. Une interface peut hériter de plusieurs interfaces de base, et une classe ou un struct peut implémenter plusieurs interfaces.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Un type délégué représente des références aux méthodes avec une liste de paramètres particulier et le type de retour.A delegate type represents references to methods with a particular parameter list and return type. Les délégués permettent de traiter les méthodes en tant qu’entités qui peuvent être affectées à des variables et passées comme paramètres.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Les délégués sont similaires au concept de pointeurs de fonction dans d’autres langages, mais contrairement aux pointeurs de fonction, les délégués sont orientés objet et de type sécurisé.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Classe, struct, interface et délégué types tous en charge les génériques, ce qui leur peuvent être paramétrés avec d’autres types.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Un type enum est un type distinct avec des constantes nommées.An enum type is a distinct type with named constants. Chaque type énumération a un type sous-jacent, ce qui doit être un des huit types intégraux.Every enum type has an underlying type, which must be one of the eight integral types. L’ensemble de valeurs d’un type enum est identique à l’ensemble de valeurs du type sous-jacent.The set of values of an enum type is the same as the set of values of the underlying type.

C# prend en charge les tableaux uni et multidimensionnels de tout type.C# supports single- and multi-dimensional arrays of any type. Contrairement aux types mentionnés ci-dessus, les types de tableaux n’ont pas à être déclarés avant de pouvoir être utilisés.Unlike the types listed above, array types do not have to be declared before they can be used. Au lieu de cela, les types de tableaux sont construits en ajoutant des crochets à un nom de type.Instead, array types are constructed by following a type name with square brackets. Par exemple, int[] est un tableau unidimensionnel de int, int[,] est un tableau bidimensionnel de int, et int[][] est un tableau unidimensionnel de tableaux unidimensionnels de int.For example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays of int.

Également, les types nullables n’ont pas à être déclarés avant de pouvoir être utilisés.Nullable types also do not have to be declared before they can be used. Pour chaque type de valeur non nullable T est un type nullable correspondant T?, qui peut contenir une valeur supplémentaire null.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Par exemple, int? est un type qui peut contenir n’importe quel entier 32 bits ou la valeur null.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#du système de type est unifié afin qu’une valeur de n’importe quel type peut être traitée en tant qu’objet.C#'s type system is unified such that a value of any type can be treated as an object. Chaque type dans C# dérive directement ou indirectement du type object, et object est la classe de base fondamentale de tous les types.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Les valeurs des types référence sont considérées comme des objets simplement en affichant les valeurs en tant que type object.Values of reference types are treated as objects simply by viewing the values as type object. Valeurs des types valeur sont traitées en tant qu’objets en effectuant boxing et unboxing operations.Values of value types are treated as objects by performing boxing and unboxing operations. Dans l’exemple suivant, une valeur int est convertie en object et à nouveau en int.In the following example, an int value is converted to object and back again to int.

using System;

class Test
{
    static void Main() {
        int i = 123;
        object o = i;          // Boxing
        int j = (int)o;        // Unboxing
    }
}

Quand une valeur d’un type valeur est convertie en type object, une instance d’objet, également appelée « boîte », est allouée pour contenir la valeur et la valeur est copiée dans cette zone.When a value of a value type is converted to type object, an object instance, also called a "box," is allocated to hold the value, and the value is copied into that box. À l’inverse, lorsque un object référence est castée en un type valeur, une vérification est effectuée que l’objet référencé est une boîte du bon type valeur, et, si la vérification réussit, la valeur dans la zone est copiée.Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

C#unifié de type de système signifie que les types valeur peuvent devenir des objets « à la demande ».C#'s unified type system effectively means that value types can become objects "on demand." En raison de l’unification, les bibliothèques à usage général qui utilisent le type object peuvent être utilisées avec les types référence et les types valeur.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

Il existe plusieurs types de variables en C#, y compris les champs, les éléments de tableau, les variables locales et les paramètres.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Les variables représentent des emplacements de stockage, et chaque variable possède un type qui détermine les valeurs pouvant être stockées dans la variable, comme indiqué dans le tableau suivant.Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown by the following table.

Type de VariableType of Variable Contenu possiblePossible Contents
Type de valeur n’acceptant pas NullNon-nullable value type Une valeur de ce type exactA value of that exact type
Types valeur NullableNullable value type Une valeur null ou une valeur de ce type exactA null value or a value of that exact type
object Une référence null, une référence à un objet de n’importe quel type de référence ou une référence à une valeur boxed de n’importe quel type de valeurA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
Type de classeClass type Une référence null, une référence à une instance de ce type de classe ou une référence à une instance d’une classe dérivée de ce type de classeA null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
Type d'interfaceInterface type Une référence null, une référence à une instance d’un type de classe qui implémente ce type d’interface ou une référence à une valeur boxed d’un type valeur qui implémente ce type d’interfaceA null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
Type tableauArray type Une référence null, une référence à une instance de ce type de tableau ou une référence à une instance d’un type tableau compatibleA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
Type déléguéDelegate type Une référence null ou une référence à une instance de ce type de déléguéA null reference or a reference to an instance of that delegate type

ExpressionsExpressions

Les expressions sont construites à partir de d’opérandes et d’opérateurs.Expressions are constructed from operands and operators. Les opérateurs d’une expression indiquent les opérations à appliquer aux opérandes.The operators of an expression indicate which operations to apply to the operands. Parmi les exemples d’opérateurs figurent +, -, *, / et new.Examples of operators include +, -, *, /, and new. Les littéraux, les champs, les variables locales et les expressions sont des exemples d’opérandes.Examples of operands include literals, fields, local variables, and expressions.

Quand une expression contient plusieurs opérateurs, la priorité des opérateurs contrôle l'ordre dans lequel les opérateurs individuels sont évalués.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. Par exemple, l’expression x + y * z est évaluée comme x + (y * z), car l’opérateur * a une priorité plus élevée que +.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

La plupart des opérateurs peuvent être surchargés.Most operators can be overloaded. La surcharge d’opérateur autorise la spécification d’implémentations d’opérateurs définies par l’utilisateur pour les opérations où l’un des deux opérandes ou les deux sont d’un type classe ou struct défini par l’utilisateur.Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.

Le tableau suivant récapitule C#d’opérateurs répertoriant les catégories d’opérateurs dans l’ordre de priorité, du plus élevé au plus bas.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Les opérateurs de la même catégorie ont la même priorité.Operators in the same category have equal precedence.

CatégorieCategory ExpressionExpression DescriptionDescription
PrincipalePrimary x.m Accès au membreMember access
x(...) Méthode et appel de déléguéMethod and delegate invocation
x[...] Tableau et accès d'indexeurArray and indexer access
x++ Post-incrémentationPost-increment
x-- Post-décrémentationPost-decrement
new T(...) Création d'objet et de déléguéObject and delegate creation
new T(...){...} Création d’objet avec initialiseurObject creation with initializer
new {...} Initialiseur d’objet anonymeAnonymous object initializer
new T[...] Création de tableauArray creation
typeof(T) Obtenir l’objet System.Type de TObtain System.Type object for T
checked(x) Évaluer l'expression dans le contexte vérifié (checked)Evaluate expression in checked context
unchecked(x) Évaluer l'expression dans le contexte non vérifié (unchecked)Evaluate expression in unchecked context
default(T) Obtenir la valeur par défaut du type TObtain default value of type T
delegate {...} Fonction anonyme (méthode anonyme)Anonymous function (anonymous method)
UnaireUnary +x IdentitéIdentity
-x NégationNegation
!x Négation logiqueLogical negation
~x Négation d'opération de bitsBitwise negation
++x Pré-incrémentationPre-increment
--x Pré-décrémentationPre-decrement
(T)x Convertir explicitement x en type TExplicitly convert x to type T
await x Attendre de façon asynchrone la fin de xAsynchronously wait for x to complete
MultiplicationMultiplicative x * y MultiplicationMultiplication
x / y DivisionDivision
x % y ResteRemainder
AdditionAdditive x + y Addition, concaténation de chaînes, combinaison de déléguésAddition, string concatenation, delegate combination
x - y Soustraction, suppression de déléguéSubtraction, delegate removal
ShiftShift x << y Décalage à gaucheShift left
x >> y Décalage à droiteShift right
Relations et test de typeRelational and type testing x < y Inférieur àLess than
x > y Supérieur àGreater than
x <= y Inférieur ou égal àLess than or equal
x >= y Supérieur ou égal àGreater than or equal
x is T Retourne true si x est un T, false sinonReturn true if x is a T, false otherwise
x as T Retourne x de type T, ou null si x n’est pas un TReturn x typed as T, or null if x is not a T
ÉgalitéEquality x == y ÉgalEqual
x != y DifférenceNot equal
AND logiqueLogical AND x & y AND d’entiers au niveau du bit, AND logique booléenInteger bitwise AND, boolean logical AND
XOR logiqueLogical XOR x ^ y Opération de bits entière XOR, Boolean logique XORInteger bitwise XOR, boolean logical XOR
OR logiqueLogical OR x | y Opération de bits entière OR, Boolean logique ORInteger bitwise OR, boolean logical OR
AND conditionnelConditional AND x && y Prend la valeur y uniquement si x est trueEvaluates y only if x is true
OR conditionnelConditional OR x || y Prend la valeur y uniquement si x est falseEvaluates y only if x is false
Fusion de NullNull coalescing x ?? y Prend la valeur y si x est nullà x sinonEvaluates to y if x is null, to x otherwise
ConditionnelConditional x ? y : z Prend la valeur y si x est true, z si x est falseEvaluates y if x is true, z if x is false
Attribution ou fonction anonymeAssignment or anonymous function x = y AttributionAssignment
x op= y Assignation composée ; opérateurs pris en charge sont *= /= %= += -= <<= >>= &= ^= |=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Fonction anonyme (expression lambda)Anonymous function (lambda expression)

InstructionsStatements

Les actions d’un programme sont exprimées à l’aide d’instructions.The actions of a program are expressed using statements. C# prend en charge plusieurs types d’instructions, dont plusieurs sont définies en termes d’instructions incorporées.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Un bloc autorise l’écriture de plusieurs instructions dans les contextes où une seule instruction est autorisée.A block permits multiple statements to be written in contexts where a single statement is allowed. Un bloc se compose d’une liste d’instructions écrites entre les délimiteurs { et }.A block consists of a list of statements written between the delimiters { and }.

Les instructions de déclaration sont utilisées pour déclarer des variables locales et des constantes.Declaration statements are used to declare local variables and constants.

Les instructions d’expression sont utilisées pour évaluer des expressions.Expression statements are used to evaluate expressions. Expressions qui peuvent être utilisées en tant qu’instructions comprennent les appels de méthode, allocations d’objet avec la new opérateur, les affectations avec = et opérateurs d’assignation composée, les opérations d’incrémentation et de décrémentation à l’aide de la ++et -- opérateurs et expressions await.Expressions that can be used as statements include method invocations, object allocations using the new operator, assignments using = and the compound assignment operators, increment and decrement operations using the ++ and -- operators and await expressions.

Les instructions de sélection sont utilisées pour sélectionner un nombre d’instructions possibles pour l’exécution en fonction de la valeur d’une expression.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. Dans ce groupe, ce sont les instructions if et switch.In this group are the if and switch statements.

Instructions d’itération servent à exécuter à plusieurs reprises une instruction incorporée.Iteration statements are used to repeatedly execute an embedded statement. Dans ce groupe, ce sont les instructions while, do, for et foreach.In this group are the while, do, for, and foreach statements.

Les instructions de saut sont utilisées pour transférer le contrôle.Jump statements are used to transfer control. Dans ce groupe, ce sont les instructions break, continue, goto, throw, return et yield.In this group are the break, continue, goto, throw, return, and yield statements.

L’instruction try...catch est utilisée pour intercepter les exceptions qui se produisent pendant l’exécution d’un bloc, et l’instruction try...finally permet de spécifier que le code de finalisation est toujours exécuté, qu’une exception se soit produite ou non.The try...catch statement is used to catch exceptions that occur during execution of a block, and the try...finally statement is used to specify finalization code that is always executed, whether an exception occurred or not.

Le checked et unchecked instructions permettent de contrôler le contexte pour les opérations arithmétiques de type intégral et les conversions de vérification de dépassement de capacité.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

L’instruction lock est utilisée pour obtenir le verrou d’exclusion mutuelle pour un objet donné, exécuter une instruction, puis libérer le verrou.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

L’instruction using est utilisée pour obtenir une ressource, exécuter une instruction puis supprimer cette ressource.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Voici des exemples de chaque type d’instructionBelow are examples of each kind of statement

Déclarations de variables localesLocal variable declarations

static void Main() {
   int a;
   int b = 2, c = 3;
   a = 1;
   Console.WriteLine(a + b + c);
}

Déclaration de constante localeLocal constant declaration

static void Main() {
    const float pi = 3.1415927f;
    const int r = 25;
    Console.WriteLine(pi * r * r);
}

Instruction d’expressionExpression statement

static void Main() {
    int i;
    i = 123;                // Expression statement
    Console.WriteLine(i);   // Expression statement
    i++;                    // Expression statement
    Console.WriteLine(i);   // Expression statement
}

instruction ifif statement

static void Main(string[] args) {
    if (args.Length == 0) {
        Console.WriteLine("No arguments");
    }
    else {
        Console.WriteLine("One or more arguments");
    }
}

instruction switchswitch statement

static void Main(string[] args) {
    int n = args.Length;
    switch (n) {
        case 0:
            Console.WriteLine("No arguments");
            break;
        case 1:
            Console.WriteLine("One argument");
            break;
        default:
            Console.WriteLine("{0} arguments", n);
            break;
    }
}

instruction whilewhile statement

static void Main(string[] args) {
    int i = 0;
    while (i < args.Length) {
        Console.WriteLine(args[i]);
        i++;
    }
}

instruction dodo statement

static void Main() {
    string s;
    do {
        s = Console.ReadLine();
        if (s != null) Console.WriteLine(s);
    } while (s != null);
}

instruction forfor statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        Console.WriteLine(args[i]);
    }
}

instruction foreachforeach statement

static void Main(string[] args) {
    foreach (string s in args) {
        Console.WriteLine(s);
    }
}

instruction breakbreak statement

static void Main() {
    while (true) {
        string s = Console.ReadLine();
        if (s == null) break;
        Console.WriteLine(s);
    }
}

instruction continuecontinue statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        if (args[i].StartsWith("/")) continue;
        Console.WriteLine(args[i]);
    }
}

instruction gotogoto statement

static void Main(string[] args) {
    int i = 0;
    goto check;
    loop:
    Console.WriteLine(args[i++]);
    check:
    if (i < args.Length) goto loop;
}

instruction returnreturn statement

static int Add(int a, int b) {
    return a + b;
}

static void Main() {
    Console.WriteLine(Add(1, 2));
    return;
}

instruction yieldyield statement

static IEnumerable<int> Range(int from, int to) {
    for (int i = from; i < to; i++) {
        yield return i;
    }
    yield break;
}

static void Main() {
    foreach (int x in Range(-10,10)) {
        Console.WriteLine(x);
    }
}

throw et try instructionsthrow and try statements

static double Divide(double x, double y) {
    if (y == 0) throw new DivideByZeroException();
    return x / y;
}

static void Main(string[] args) {
    try {
        if (args.Length != 2) {
            throw new Exception("Two numbers required");
        }
        double x = double.Parse(args[0]);
        double y = double.Parse(args[1]);
        Console.WriteLine(Divide(x, y));
    }
    catch (Exception e) {
        Console.WriteLine(e.Message);
    }
    finally {
        Console.WriteLine("Good bye!");
    }
}

checked et unchecked instructionschecked and unchecked statements

static void Main() {
    int i = int.MaxValue;
    checked {
        Console.WriteLine(i + 1);        // Exception
    }
    unchecked {
        Console.WriteLine(i + 1);        // Overflow
    }
}

instruction locklock statement

class Account
{
    decimal balance;
    public void Withdraw(decimal amount) {
        lock (this) {
            if (amount > balance) {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

instruction usingusing statement

static void Main() {
    using (TextWriter w = File.CreateText("test.txt")) {
        w.WriteLine("Line one");
        w.WriteLine("Line two");
        w.WriteLine("Line three");
    }
}

Classes et objetsClasses and objects

Les classes représentent le type le plus fondamental de C#.Classes are the most fundamental of C#'s types. Une classe est une structure de données qui combine l’état (champs) et les actions (méthodes et autres fonctions membres) en une seule unité.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Une classe fournit une définition pour les instances créées dynamiquement de la classe, également appelées objets.A class provides a definition for dynamically created instances of the class, also known as objects. Les classes prennent en charge l’héritage et le polymorphisme, des mécanismes par lesquels les classes dérivées peuvent étendre et spécialiser les classes de base.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Les nouvelles classes sont créées à l’aide des déclarations de classe.New classes are created using class declarations. Une déclaration de classe commence par un en-tête qui spécifie les attributs et modificateurs de la classe, le nom de la classe, la classe de base (si fournie) et les interfaces implémentées par la classe.A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. L’en-tête est suivi par le corps de la classe, qui se compose d’une liste de déclarations de membres écrites entre les délimiteurs { et }.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Voici une déclaration d’une classe simple nommée Point :The following is a declaration of a simple class named Point:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Les instances de classes sont créées à l’aide de l’opérateur new, qui alloue la mémoire pour une nouvelle instance, appelle un constructeur pour initialiser l’instance et retourne une référence à l’instance.Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. Les instructions suivantes créent deux Point objets et de stocker les références à ces objets dans les deux variables :The following statements create two Point objects and store references to those objects in two variables:

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

La mémoire occupée par un objet est automatiquement libérée lorsque l’objet n’est plus en cours d’utilisation.The memory occupied by an object is automatically reclaimed when the object is no longer in use. Il n’est ni possible ni nécessaire de libérer explicitement des objets dans C#.It is neither necessary nor possible to explicitly deallocate objects in C#.

MembresMembers

Les membres d’une classe sont soit membres statiques ou membres d’instance.The members of a class are either static members or instance members. Les membres statiques appartiennent à des classes, et les membres d’instance appartiennent à des objets (instances de classes).Static members belong to classes, and instance members belong to objects (instances of classes).

Le tableau suivant fournit une vue d’ensemble des types de membres de qu'une classe peut contenir.The following table provides an overview of the kinds of members a class can contain.

MembreMember DescriptionDescription
ConstantesConstants Valeurs constantes associées à la classeConstant values associated with the class
ChampsFields Variables de la classeVariables of the class
MéthodesMethods Calculs et les actions qui peuvent être effectués par la classeComputations and actions that can be performed by the class
PropriétésProperties Actions associées à la lecture et l’écriture des propriétés nommées de la classeActions associated with reading and writing named properties of the class
IndexeursIndexers Actions liées à l’indexation des instances de la classe comme un tableauActions associated with indexing instances of the class like an array
ÉvénementsEvents Les notifications qui peuvent être générées par la classeNotifications that can be generated by the class
OpérateursOperators Les opérateurs de conversion et d’expression pris en charge par la classeConversions and expression operators supported by the class
ConstructeursConstructors Les actions requises pour initialiser les instances de la classe ou la classe elle-mêmeActions required to initialize instances of the class or the class itself
DestructeursDestructors Actions à effectuer avant que les instances de la classe soient abandonnées de façon définitiveActions to perform before instances of the class are permanently discarded
TypesTypes Types imbriqués déclarés par la classeNested types declared by the class

AccessibilitéAccessibility

Chaque membre d’une classe a une accessibilité associée, qui contrôle les régions du texte du programme qui sont en mesure d’accéder au membre.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Il existe cinq formes possibles d’accessibilité.There are five possible forms of accessibility. Ceux-ci sont résumés dans le tableau ci-après.These are summarized in the following table.

AccessibilitéAccessibility SignificationMeaning
public Accès non limitéAccess not limited
protected Accès limité à cette classe ou aux classes dérivées de cette classeAccess limited to this class or classes derived from this class
internal Accès limité à ce programmeAccess limited to this program
protected internal Accès limité à ce programme ou aux classes dérivées de cette classeAccess limited to this program or classes derived from this class
private Accès limité à cette classeAccess limited to this class

Paramètres de typeType parameters

Une définition de classe peut spécifier un jeu de paramètres de type en faisant suivre le nom de classe par une liste de noms de paramètre de type entre crochets.A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. Les paramètres de type peuvent l’être utilisé dans le corps des déclarations de classe pour définir les membres de la classe.The type parameters can the be used in the body of the class declarations to define the members of the class. Dans l’exemple suivant, les paramètres de type de Pair sont TFirst et TSecond :In the following example, the type parameters of Pair are TFirst and TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

Un type de classe est déclaré pour prendre des paramètres de type est appelé un type de classe générique.A class type that is declared to take type parameters is called a generic class type. Les types struct, interface et délégué peuvent également être génériques.Struct, interface and delegate types can also be generic.

Lorsque la classe générique est utilisée, des arguments de type doivent être fournis pour chacun des paramètres de type :When the generic class is used, type arguments must be provided for each of the type parameters:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

Un type générique avec des arguments de type fournis, comme Pair<int,string> ci-dessus, est appelé type construit.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

Classes de baseBase classes

Une déclaration de classe peut spécifier une classe de base en faisant suivre les paramètres de nom et de type de classe par un signe deux-points et le nom de la classe de base.A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. L’omission d’une spécification de classe de base revient à dériver du type object.Omitting a base class specification is the same as deriving from type object. Dans l'exemple suivant, la classe de base de Point3D est Point, et la classe de base de Point est object :In the following example, the base class of Point3D is Point, and the base class of Point is object:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Point3D: Point
{
    public int z;

    public Point3D(int x, int y, int z): base(x, y) {
        this.z = z;
    }
}

Une classe hérite des membres de sa classe de base.A class inherits the members of its base class. L’héritage signifie qu’une classe contient implicitement tous les membres de sa classe de base, à l’exception de l’instance et les constructeurs statiques et les destructeurs de classe de base.Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the destructors of the base class. Une classe dérivée peut ajouter des membres hérités, mais ne peut pas supprimer la définition d’un membre hérité.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. Dans l’exemple précédent, Point3D hérite des champs x et y de Point, et chaque instance de Point3D contient trois champs, x, y et z.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

Il existe une conversion implicite d’un type de classe vers un de ses types de classe de base.An implicit conversion exists from a class type to any of its base class types. Par conséquent, une variable d’un type de classe peut référencer une instance de cette classe ou une instance d’une classe dérivée.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Par exemple, pour les déclarations de classe précédentes, une variable de type Point peut faire référence à un objet Point ou Point3D :For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

ChampsFields

Un champ est une variable qui est associée à une classe ou à une instance d’une classe.A field is a variable that is associated with a class or with an instance of a class.

Un champ déclaré avec le static modificateur définit un champ statique.A field declared with the static modifier defines a static field. Un champ statique identifie exactement un seul emplacement de stockage.A static field identifies exactly one storage location. Quel que soit le nombre d’instances d’une classe qui sont créées, il n’existe qu’une seule copie d’un champ statique.No matter how many instances of a class are created, there is only ever one copy of a static field.

Un champ déclaré sans le static modificateur définit un champ d’instance.A field declared without the static modifier defines an instance field. Chaque instance d’une classe contient une copie distincte de tous les champs d’instance de cette classe.Every instance of a class contains a separate copy of all the instance fields of that class.

Dans l’exemple suivant, chaque instance de la classe Color possède une copie distincte des champs d’instance r, g et b, mais il existe une seule copie des champs statiques Black, White, Red, Green et Blue :In the following example, each instance of the Color class has a separate copy of the r, g, and b instance fields, but there is only one copy of the Black, White, Red, Green, and Blue static fields:

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte r, g, b;

    public Color(byte r, byte g, byte b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

Comme indiqué dans l’exemple précédent, les champs en lecture seule peuvent être déclarés avec un modificateur readonly.As shown in the previous example, read-only fields may be declared with a readonly modifier. Affectation à un readonly champ peut se produire uniquement dans le cadre de la déclaration du champ ou dans un constructeur de la même classe.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

MéthodesMethods

Une méthode est un membre qui implémente un calcul ou une action qui peut être effectuée par un objet ou une classe.A method is a member that implements a computation or action that can be performed by an object or class. Les méthodes statiques sont accessibles à travers la classe.Static methods are accessed through the class. Les méthodes d’instance sont accessibles via des instances de la classe.Instance methods are accessed through instances of the class.

Méthodes ont une liste (éventuellement vide) de paramètres, qui représentent des valeurs ou des références variables passées à la méthode et un type de retour, qui spécifie le type de la valeur calculée et retournée par la méthode.Methods have a (possibly empty) list of parameters, which represent values or variable references passed to the method, and a return type, which specifies the type of the value computed and returned by the method. Type de retour d’une méthode est void si elle ne retourne pas une valeur.A method's return type is void if it does not return a value.

Comme les types, les méthodes peuvent également être un jeu de paramètres de type pour lesquels les arguments de type doivent être spécifiés lorsque la méthode est appelée.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Contrairement aux types, les arguments de type peuvent souvent être déduits à partir des arguments d’un appel de méthode et n’ont pas à être fournis explicitement.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

La signature d’une méthode doit être unique dans la classe dans laquelle la méthode est déclarée.The signature of a method must be unique in the class in which the method is declared. La signature d’une méthode se compose du nom de la méthode, du nombre de paramètres de type et du nombre, des modificateurs et des types de ses paramètres.The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. La signature d'une méthode n'inclut pas le type de retour.The signature of a method does not include the return type.

ParamètresParameters

Les paramètres sont utilisés pour passer des valeurs ou des références variables aux méthodes.Parameters are used to pass values or variable references to methods. Les paramètres d’une méthode obtiennent leurs valeurs réelles à partir des arguments qui sont spécifiés lorsque la méthode est appelée.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Il existe quatre types de paramètres : les paramètres de valeur, les paramètres de référence, les paramètres de sortie et les tableaux de paramètres.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Un paramètre de valeur est utilisé pour le passage de paramètres d’entrée.A value parameter is used for input parameter passing. Un paramètre de valeur correspond à une variable locale qui obtient sa valeur initiale de l’argument qui a été transmis pour le paramètre.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Les modifications apportées à un paramètre de valeur n’affectent pas l’argument qui a été transmis pour le paramètre.Modifications to a value parameter do not affect the argument that was passed for the parameter.

Les paramètres de valeur peuvent être facultatifs, en spécifiant une valeur par défaut afin que les arguments correspondants puissent être omis.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Un paramètre de référence est utilisé pour la transmission de paramètres en entrée et en sortie.A reference parameter is used for both input and output parameter passing. L’argument passé pour un paramètre de référence doit être une variable, et pendant l’exécution de la méthode, le paramètre de référence représente le même emplacement de stockage que la variable d’argument.The argument passed for a reference parameter must be a variable, and during execution of the method, the reference parameter represents the same storage location as the argument variable. Un paramètre de référence est déclaré avec le modificateur ref.A reference parameter is declared with the ref modifier. L'exemple suivant illustre l'utilisation des paramètres ref.The following example shows the use of ref parameters.

using System;

class Test
{
    static void Swap(ref int x, ref int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    static void Main() {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine("{0} {1}", i, j);            // Outputs "2 1"
    }
}

Un paramètre de sortie est utilisé pour le passage de paramètres de sortie.An output parameter is used for output parameter passing. Un paramètre de sortie est similaire à un paramètre de référence, sauf que la valeur initiale de l’argument fourni par l’appelant n’a pas d’importance.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Un paramètre de sortie est déclaré avec le modificateur out.An output parameter is declared with the out modifier. L'exemple suivant illustre l'utilisation des paramètres out.The following example shows the use of out parameters.

using System;

class Test
{
    static void Divide(int x, int y, out int result, out int remainder) {
        result = x / y;
        remainder = x % y;
    }

    static void Main() {
        int res, rem;
        Divide(10, 3, out res, out rem);
        Console.WriteLine("{0} {1}", res, rem);    // Outputs "3 1"
    }
}

Un tableau de paramètres autorise le passage d’un nombre variable d’arguments à une méthode.A parameter array permits a variable number of arguments to be passed to a method. Un tableau de paramètres est déclaré avec le modificateur params.A parameter array is declared with the params modifier. Seul le dernier paramètre d’une méthode peut être un tableau de paramètres, et le type d’un tableau de paramètres doit être un type tableau unidimensionnel.Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. Le Write et WriteLine méthodes de la System.Console classe sont de bons exemples d’utilisation des tableaux de paramètre.The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Vous les déclarez de la façon suivante.They are declared as follows.

public class Console
{
    public static void Write(string fmt, params object[] args) {...}
    public static void WriteLine(string fmt, params object[] args) {...}
    ...
}

Dans une méthode qui utilise un tableau de paramètres, le tableau de paramètres se comporte exactement comme un paramètre ordinaire de type tableau.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. Toutefois, dans un appel à une méthode avec un tableau de paramètres, il est possible de passer un argument unique de type tableau de paramètres ou n’importe quel nombre d’arguments du type d’élément du tableau de paramètres.However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. Dans ce cas, une instance de tableau est automatiquement créée et initialisée avec les arguments donnés.In the latter case, an array instance is automatically created and initialized with the given arguments. Cet exempleThis example

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

revient à écrire ce qui suit.is equivalent to writing the following.

string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Corps de la méthode et variables localesMethod body and local variables

Corps d’une méthode spécifie les instructions à exécuter lorsque la méthode est appelée.A method's body specifies the statements to execute when the method is invoked.

Un corps de méthode peut déclarer des variables qui sont spécifiques à l’appel de la méthode.A method body can declare variables that are specific to the invocation of the method. Ces variables sont appelées variables locales.Such variables are called local variables. Une déclaration de variable locale spécifie un nom de type, un nom de variable et éventuellement une valeur initiale.A local variable declaration specifies a type name, a variable name, and possibly an initial value. L’exemple suivant déclare une variable locale i avec une valeur initiale de zéro et une variable locale j sans valeur initiale.The following example declares a local variable i with an initial value of zero and a local variable j with no initial value.

using System;

class Squares
{
    static void Main() {
        int i = 0;
        int j;
        while (i < 10) {
            j = i * i;
            Console.WriteLine("{0} x {0} = {1}", i, j);
            i = i + 1;
        }
    }
}

C# requiert qu’une variable locale soit assignée de manière définitive avant de pouvoir obtenir sa valeur.C# requires a local variable to be definitely assigned before its value can be obtained. Par exemple, si la déclaration du i précédent n’inclut pas de valeur initiale, le compilateur signale une erreur pour les utilisations ultérieures de i, car i ne serait pas assigné de manière définitive à ces points dans le programme.For example, if the declaration of the previous i did not include an initial value, the compiler would report an error for the subsequent usages of i because i would not be definitely assigned at those points in the program.

Une méthode peut utiliser les instructions return pour retourner le contrôle à son appelant.A method can use return statements to return control to its caller. Dans une méthode retournant void, les instructions return ne peuvent pas spécifier une expression.In a method returning void, return statements cannot specify an expression. Dans une méthode retournant non -void, return les instructions doivent inclure une expression qui calcule la valeur de retour.In a method returning non-void, return statements must include an expression that computes the return value.

Méthodes statiques et d’instanceStatic and instance methods

Une méthode déclarée avec un static modificateur est un méthode statique.A method declared with a static modifier is a static method. Une méthode statique n’opère pas sur une instance spécifique et permet uniquement d’accéder directement à des membres statiques.A static method does not operate on a specific instance and can only directly access static members.

Une méthode déclarée sans un static modificateur est un méthode d’instance.A method declared without a static modifier is an instance method. Une méthode d’instance opère sur une instance spécifique et peut accéder aux membres statiques et d’instance.An instance method operates on a specific instance and can access both static and instance members. L’instance sur laquelle une méthode d’instance a été appelée est explicitement accessible en tant que this.The instance on which an instance method was invoked can be explicitly accessed as this. Une erreur consiste à faire référence à this dans une méthode statique.It is an error to refer to this in a static method.

La classe Entity suivante a à la fois des statiques et des membres d’instance.The following Entity class has both static and instance members.

class Entity
{
    static int nextSerialNo;
    int serialNo;

    public Entity() {
        serialNo = nextSerialNo++;
    }

    public int GetSerialNo() {
        return serialNo;
    }

    public static int GetNextSerialNo() {
        return nextSerialNo;
    }

    public static void SetNextSerialNo(int value) {
        nextSerialNo = value;
    }
}

Chaque instance Entity contient un numéro de série (et probablement d’autres informations qui ne sont pas indiquées ici).Each Entity instance contains a serial number (and presumably some other information that is not shown here). Le constructeur Entity (qui est similaire à une méthode d’instance) initialise la nouvelle instance avec le numéro de série suivant.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Étant donné que le constructeur est un membre d’instance, il est autorisé à accéder à la fois au champ d’instance serialNo et au champ statique nextSerialNo.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

Les méthodes statiques GetNextSerialNo et SetNextSerialNo peuvent accéder au champ statique nextSerialNo, mais ce serait une erreur pour eux d’accéder directement au champ d’instance serialNo.The GetNextSerialNo and SetNextSerialNo static methods can access the nextSerialNo static field, but it would be an error for them to directly access the serialNo instance field.

L’exemple suivant illustre l’utilisation de la Entity classe.The following example shows the use of the Entity class.

using System;

class Test
{
    static void Main() {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());           // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());           // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());   // Outputs "1002"
    }
}

Notez que les méthodes statiques SetNextSerialNo et GetNextSerialNo sont appelées sur la classe alors que la méthode d’instance GetSerialNo est appelée sur les instances de la classe.Note that the SetNextSerialNo and GetNextSerialNo static methods are invoked on the class whereas the GetSerialNo instance method is invoked on instances of the class.

Méthodes virtuelles, de substitution et abstraitesVirtual, override, and abstract methods

Lorsqu’une déclaration de méthode d’instance inclut un modificateur virtual, la méthode est appelée méthode virtuelle.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. En cas de non virtual modificateur est présent, la méthode est dite un méthode non virtuelle.When no virtual modifier is present, the method is said to be a non-virtual method.

Lorsqu’une méthode virtuelle est appelée, le type au moment de l’exécution de l’instance pour laquelle cet appel prend place détermine l’implémentation de méthode à appeler.When a virtual method is invoked, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. Dans un appel de méthode non virtuelle, le type lors de la compilation de l’instance est le facteur déterminant.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Une méthode virtuelle peut être substituée dans une classe dérivée.A virtual method can be overridden in a derived class. Lorsqu’une déclaration de méthode d’instance inclut un override modificateur, la méthode substitue à une méthode virtuelle héritée ayant la même signature.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Là où une déclaration de méthode virtuelle présente une nouvelle méthode, une déclaration de méthode de substitution spécialise une méthode virtuelle héritée existante en fournissant une nouvelle implémentation de cette méthode.Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.

Un abstraite méthode est une méthode virtuelle sans implémentation.An abstract method is a virtual method with no implementation. Une méthode abstraite est déclarée avec le abstract modificateur et n’est autorisée uniquement dans une classe qui est également déclarée abstract.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Une méthode abstraite doit être remplacée dans chaque classe dérivée non abstraite.An abstract method must be overridden in every non-abstract derived class.

L’exemple suivant déclare une classe abstraite, Expression, qui représente un nœud d’arborescence de l’expression et trois classes dérivées, Constant, VariableReference et Operation, qui implémentent des nœuds d’arborescence de l’expression pour les références variables, les constantes et les opérations arithmétiques.The following example declares an abstract class, Expression, which represents an expression tree node, and three derived classes, Constant, VariableReference, and Operation, which implement expression tree nodes for constants, variable references, and arithmetic operations. (Cela revient à, mais à ne pas confondre avec les types d’arborescence expression introduit dans types arborescence d’Expression).(This is similar to, but not to be confused with the expression tree types introduced in Expression tree types).

using System;
using System.Collections;

public abstract class Expression
{
    public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression
{
    double value;

    public Constant(double value) {
        this.value = value;
    }

    public override double Evaluate(Hashtable vars) {
        return value;
    }
}

public class VariableReference: Expression
{
    string name;

    public VariableReference(string name) {
        this.name = name;
    }

    public override double Evaluate(Hashtable vars) {
        object value = vars[name];
        if (value == null) {
            throw new Exception("Unknown variable: " + name);
        }
        return Convert.ToDouble(value);
    }
}

public class Operation: Expression
{
    Expression left;
    char op;
    Expression right;

    public Operation(Expression left, char op, Expression right) {
        this.left = left;
        this.op = op;
        this.right = right;
    }

    public override double Evaluate(Hashtable vars) {
        double x = left.Evaluate(vars);
        double y = right.Evaluate(vars);
        switch (op) {
            case '+': return x + y;
            case '-': return x - y;
            case '*': return x * y;
            case '/': return x / y;
        }
        throw new Exception("Unknown operator");
    }
}

Les quatre classes précédentes permet de modéliser des expressions arithmétiques.The previous four classes can be used to model arithmetic expressions. Par exemple, en utilisant des instances de ces classes, l’expression x + 3 peut être représentée comme suit.For example, using instances of these classes, the expression x + 3 can be represented as follows.

Expression e = new Operation(
    new VariableReference("x"),
    '+',
    new Constant(3));

La méthode Evaluate d’une instance Expression est appelée pour évaluer l’expression donnée et produire une valeur double.The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. La méthode prend comme argument une Hashtable qui contient les noms de variables (comme clés des entrées) et des valeurs (comme les valeurs des entrées).The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). Le Evaluate méthode est une méthode virtuelle abstraite, ce qui signifie que les classes non abstraites dérivées doivent remplacer pour fournir une implémentation réelle.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

Une implémentation de Constant de Evaluate renvoie simplement la constante stockée.A Constant's implementation of Evaluate simply returns the stored constant. Un VariableReferenced’implémentation recherche le nom de variable dans la table de hachage et retourne la valeur résultante.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Une implémentation de Operation évalue d’abord les opérandes de gauche et de droite (en appelant de manière récursive leurs méthodes Evaluate), puis effectue l’opération arithmétique donnée.An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

Le programme suivant utilise les classes Expression pour évaluer l’expression x * (y + 2) pour différentes valeurs de x et y.The following program uses the Expression classes to evaluate the expression x * (y + 2) for different values of x and y.

using System;
using System.Collections;

class Test
{
    static void Main() {
        Expression e = new Operation(
            new VariableReference("x"),
            '*',
            new Operation(
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        Hashtable vars = new Hashtable();
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "16.5"
    }
}

Surcharge de méthodeMethod overloading

La surcharge de méthode permet d’avoir plusieurs méthodes dans la même classe avec le même nom, tant qu’elles ont des signatures uniques.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Lors de la compilation d’un appel à une méthode surchargée, le compilateur utilise la résolution de surcharge pour déterminer la méthode spécifique à appeler.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. La résolution de surcharge trouve la méthode qui correspond le mieux aux arguments ou signale une erreur si aucune meilleure correspondance ne peut être trouvée.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. L’exemple suivant montre la résolution de surcharge en action.The following example shows overload resolution in effect. Le commentaire pour chaque appel de la méthode Main affiche une méthode qui est réellement appelée.The comment for each invocation in the Main method shows which method is actually invoked.

class Test
{
    static void F() {
        Console.WriteLine("F()");
    }

    static void F(object x) {
        Console.WriteLine("F(object)");
    }

    static void F(int x) {
        Console.WriteLine("F(int)");
    }

    static void F(double x) {
        Console.WriteLine("F(double)");
    }

    static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");
    }

    static void F(double x, double y) {
        Console.WriteLine("F(double, double)");
    }

    static void Main() {
        F();                 // Invokes F()
        F(1);                // Invokes F(int)
        F(1.0);              // Invokes F(double)
        F("abc");            // Invokes F(object)
        F((double)1);        // Invokes F(double)
        F((object)1);        // Invokes F(object)
        F<int>(1);           // Invokes F<T>(T)
        F(1, 1);             // Invokes F(double, double)
    }
}

Comme le montre l’exemple, une méthode particulière peut toujours être sélectionnée en effectuant un cast explicite des arguments aux types de paramètres exacts et/ou en fournissant explicitement les arguments de type.As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.

Autres fonctions membresOther function members

Les membres qui contiennent du code exécutable sont collectivement regroupés sous les membres de fonction d’une classe.Members that contain executable code are collectively known as the function members of a class. La section précédente décrit les méthodes qui sont du type principal des fonctions membres.The preceding section describes methods, which are the primary kind of function members. Cette section décrit les autres types de fonctions membres pris en charge par c# : constructeurs, propriétés, indexeurs, événements, opérateurs et les destructeurs.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Le code suivant montre une classe générique appelée List<T>, qui implémente une liste d’objets évolutive.The following code shows a generic class called List<T>, which implements a growable list of objects. La classe contient plusieurs exemples des types les plus courants de membres de fonction.The class contains several examples of the most common kinds of function members.

public class List<T> {
    // Constant...
    const int defaultCapacity = 4;

    // Fields...
    T[] items;
    int count;

    // Constructors...
    public List(int capacity = defaultCapacity) {
        items = new T[capacity];
    }

    // Properties...
    public int Count {
        get { return count; }
    }
    public int Capacity {
        get {
            return items.Length;
        }
        set {
            if (value < count) value = count;
            if (value != items.Length) {
                T[] newItems = new T[value];
                Array.Copy(items, 0, newItems, 0, count);
                items = newItems;
            }
        }
    }

    // Indexer...
    public T this[int index] {
        get {
            return items[index];
        }
        set {
            items[index] = value;
            OnChanged();
        }
    }

    // Methods...
    public void Add(T item) {
        if (count == Capacity) Capacity = count * 2;
        items[count] = item;
        count++;
        OnChanged();
    }
    protected virtual void OnChanged() {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public override bool Equals(object other) {
        return Equals(this, other as List<T>);
    }
    static bool Equals(List<T> a, List<T> b) {
        if (a == null) return b == null;
        if (b == null || a.count != b.count) return false;
        for (int i = 0; i < a.count; i++) {
            if (!object.Equals(a.items[i], b.items[i])) {
                return false;
            }
        }
        return true;
    }

    // Event...
    public event EventHandler Changed;

    // Operators...
    public static bool operator ==(List<T> a, List<T> b) {
        return Equals(a, b);
    }
    public static bool operator !=(List<T> a, List<T> b) {
        return !Equals(a, b);
    }
}

ConstructeursConstructors

C# prend en charge les constructeurs statiques et d’instance.C# supports both instance and static constructors. Un constructeur d’instance est un membre qui implémente les actions requises pour initialiser une instance d’une classe.An instance constructor is a member that implements the actions required to initialize an instance of a class. Un constructeur statique est un membre qui implémente les actions requises pour initialiser une classe lui-même lorsqu’il est chargé.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Un constructeur est déclaré comme une méthode sans aucun type de retour et le même nom que la classe contenante.A constructor is declared like a method with no return type and the same name as the containing class. Si une déclaration de constructeur comprend un static modificateur, elle déclare un constructeur statique.If a constructor declaration includes a static modifier, it declares a static constructor. Dans le cas contraire, elle déclare un constructeur d’instance.Otherwise, it declares an instance constructor.

Constructeurs d’instance peuvent être surchargés.Instance constructors can be overloaded. Par exemple, la classe List<T> déclare deux constructeurs d’instance, un sans paramètres et une fonction qui accepte un paramètre int.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. Les constructeurs d’instance sont appelés en utilisant l’opérateur new.Instance constructors are invoked using the new operator. Les instructions suivantes allouent deux List<string> instances à l’aide de chacun des constructeurs de la List classe.The following statements allocate two List<string> instances using each of the constructors of the List class.

List<string> list1 = new List<string>();
List<string> list2 = new List<string>(10);

Contrairement aux autres membres, les constructeurs d’instance ne sont pas hérités, et une classe n’a aucun constructeur d’instance autre que ceux réellement déclarés dans la classe.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. Si aucun constructeur d’instance n’est fourni pour une classe, un constructeur vide sans paramètre est fourni automatiquement.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

PropriétésProperties

Les propriétés sont une extension naturelle des champs.Properties are a natural extension of fields. Les deux sont des membres nommés avec des types associés, et la syntaxe pour accéder aux champs et propriétés est la même.Both are named members with associated types, and the syntax for accessing fields and properties is the same. Toutefois, contrairement aux champs, les propriétés ne désignent pas des emplacements de stockage.However, unlike fields, properties do not denote storage locations. Au lieu de cela, les propriétés ont des accesseurs qui spécifient les instructions à exécuter lorsque les valeurs sont lues ou écrites.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Une propriété est déclarée comme un champ, à ceci près que la déclaration se termine par un get accesseur et/ou un set accesseur écrite entre les délimiteurs { et } au lieu de se terminant par un point-virgule.A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. Une propriété qui possède à la fois un get accesseur et un set accesseur est une propriété en lecture-écriture, une propriété qui possède uniquement un get accesseur est une propriété en lecture seuleet un propriété qui a uniquement un set accesseur est une propriété en écriture seule.A property that has both a get accessor and a set accessor is a read-write property, a property that has only a get accessor is a read-only property, and a property that has only a set accessor is a write-only property.

Un get accesseur correspond à une méthode sans paramètre avec une valeur de retour du type de propriété.A get accessor corresponds to a parameterless method with a return value of the property type. À l’exception comme cible d’une assignation, lorsqu’une propriété est référencée dans une expression, le get accesseur de la propriété est appelé pour calculer la valeur de la propriété.Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.

Un set accesseur correspond à une méthode avec un paramètre unique nommé value et aucun type de retour.A set accessor corresponds to a method with a single parameter named value and no return type. Lorsqu’une propriété est référencée en tant que la cible d’une assignation ou l’opérande de ++ ou --, le set accesseur est appelé avec un argument qui fournit la nouvelle valeur.When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.

La classe List<T> déclare deux propriétés, Count et Capacity, qui sont respectivement en lecture seule et en lecture-écriture.The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. Voici un exemple d’utilisation de ces propriétés.The following is an example of use of these properties.

List<string> names = new List<string>();
names.Capacity = 100;            // Invokes set accessor
int i = names.Count;             // Invokes get accessor
int j = names.Capacity;          // Invokes get accessor

C# prend en charge les propriétés d’instance et les propriétés statiques, similaires aux champs et aux méthodes.Similar to fields and methods, C# supports both instance properties and static properties. Propriétés statiques sont déclarées avec le static modificateur et les propriétés de l’instance sont déclarées sans.Static properties are declared with the static modifier, and instance properties are declared without it.

Le ou les accesseurs d’une propriété peuvent être virtuels.The accessor(s) of a property can be virtual. Lorsqu’une déclaration de propriété inclut un modificateur virtual, abstract ou override, elle s’applique aux accesseurs de la propriété.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndexeursIndexers

Un indexeur est un membre qui permet l’indexation des objets de la même façon en tant que tableau.An indexer is a member that enables objects to be indexed in the same way as an array. Un indexeur est déclaré comme une propriété, sauf que le nom du membre est this suivie d’une liste de paramètres écrite entre les délimiteurs [ et ].An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ]. Les paramètres sont disponibles dans le ou les accesseurs de l’indexeur.The parameters are available in the accessor(s) of the indexer. Similaires aux propriétés, les indexeurs peuvent être en lecture-écriture, en lecture seule et en écriture seule, et les accesseurs d’un indexeur peuvent être virtuels.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

La classe List déclare un indexeur en lecture-écriture unique qui prend un paramètre int.The List class declares a single read-write indexer that takes an int parameter. L’indexeur rend possible l’indexation des instances List avec des valeurs int.The indexer makes it possible to index List instances with int values. Exemple :For example

List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
    string s = names[i];
    names[i] = s.ToUpper();
}

Les indexeurs peuvent être surchargés, ce qui signifie qu’une classe peut déclarer plusieurs indexeurs tant que le nombre ou les types de leurs paramètres diffèrent.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

ÉvénementsEvents

Un événement est un membre qui permet à une classe ou un objet de fournir des notifications.An event is a member that enables a class or object to provide notifications. Un événement est déclaré comme un champ, à ceci près que la déclaration inclut un event mot clé et le type doivent être un type délégué.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

Dans une classe qui déclare un membre d’événement, l’événement se comporte comme un champ d’un type délégué (à condition que l’événement n’est pas abstrait et ne déclare pas d’accesseurs).Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). Le champ stocke une référence à un délégué qui représente les gestionnaires d’événements qui ont été ajoutés à l’événement.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Si aucun handle d’événement n’est présents, le champ est null.If no event handles are present, the field is null.

La classe List<T> déclare un membre d’événement unique appelé Changed, qui indique qu’un nouvel élément a été ajouté à la liste.The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. Le Changed événement est déclenché par le OnChanged méthode virtuelle, qui vérifie si l’événement est null (ce qui signifie qu’aucun gestionnaire n’est présent).The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). La notion de déclenchement d’un événement est équivalente à l’appel de délégué représenté par l’événement. Par conséquent, il n’existe aucune construction de langage particulière pour déclencher des événements.The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

Les clients réagissent aux événements via les gestionnaires d’événements.Clients react to events through event handlers. Les gestionnaires d’événements sont joints à l’aide de l’opérateur += et supprimés à l’aide de l’opérateur -=.Event handlers are attached using the += operator and removed using the -= operator. L'exemple suivant joint un gestionnaire d'événements à l'événement Changed d’un List<string>.The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
    static int changeCount;

    static void ListChanged(object sender, EventArgs e) {
        changeCount++;
    }

    static void Main() {
        List<string> names = new List<string>();
        names.Changed += new EventHandler(ListChanged);
        names.Add("Liz");
        names.Add("Martha");
        names.Add("Beth");
        Console.WriteLine(changeCount);        // Outputs "3"
    }
}

Pour les scénarios avancés où le contrôle du stockage sous-jacent d’un événement est souhaité, une déclaration d’événement peut fournir explicitement des accesseurs add et remove, qui sont plutôt similaires à l’accesseur set d’une propriété.For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

OpérateursOperators

Un opérateur est un membre qui définit la signification de l’application d’un opérateur d’expression particulière aux instances d’une classe.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. Trois types d’opérateurs peuvent être définis : les opérateurs unaires, les opérateurs binaires et les opérateurs de conversion.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Tous les opérateurs doivent être déclarés comme public et static.All operators must be declared as public and static.

La classe List<T> déclare deux opérateurs, operator== et operator!=, et donne donc une nouvelle signification aux expressions qui appliquent ces opérateurs aux instances List.The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. Plus précisément, les opérateurs de définissent une égalité de deux List<T> instances comme la comparaison de chacun des objets de relation contenant-contenus à l’aide de leurs Equals méthodes.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. L’exemple suivant utilise l’opérateur == pour comparer deux instances de List<int>.The following example uses the == operator to compare two List<int> instances.

using System;

class Test
{
    static void Main() {
        List<int> a = new List<int>();
        a.Add(1);
        a.Add(2);
        List<int> b = new List<int>();
        b.Add(1);
        b.Add(2);
        Console.WriteLine(a == b);        // Outputs "True"
        b.Add(3);
        Console.WriteLine(a == b);        // Outputs "False"
    }
}

La première Console.WriteLine génère True, car les deux listes contiennent le même nombre d’objets avec les mêmes valeurs dans le même ordre.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. Si List<T> n’avait pas défini operator==, la première Console.WriteLine aurait affiché False, car a et b référencent des instances List<int> différentes.Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

DestructeursDestructors

Un destructeur est un membre qui implémente les actions requises pour détruire une instance d’une classe.A destructor is a member that implements the actions required to destruct an instance of a class. Les destructeurs ne peuvent pas avoir de paramètres, ils ne peuvent pas avoir de modificateurs d’accessibilité et ils ne peuvent pas être appelés explicitement.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Le destructeur d’une instance est appelé automatiquement lors du garbage collection.The destructor for an instance is invoked automatically during garbage collection.

Le garbage collector est autorisé à toute latitude pour déterminer quand collecter des objets et exécuter des destructeurs.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Plus précisément, le minutage des appels de destructeur n’est pas déterministe, et les destructeurs ne peuvent être exécutés sur n’importe quel thread.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Pour ces raisons et d’autres, les classes doivent implémenter des destructeurs uniquement lorsque aucune des autres solutions ne sont envisageables.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

L’instruction using fournit une meilleure approche pour la destruction d’objets.The using statement provides a better approach to object destruction.

StructsStructs

Comme les classes, les structs sont des structures de données qui peuvent contenir des membres de données et des fonctions membres. Mais contrairement aux classes, les structures sont des types valeur et ne nécessitent pas d’allocation de tas.Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. Une variable de type struct stocke directement les données de la structure, alors qu’une variable de type class stocke une référence à un objet alloué dynamiquement.A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. Les types struct ne prennent pas en charge l’héritage spécifié par l’utilisateur, et tous les types struct héritent implicitement du type object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Les structures sont particulièrement utiles pour les petites structures de données qui ont une sémantique par rapport à leurs valeurs.Structs are particularly useful for small data structures that have value semantics. Les nombres complexes, les points dans un système de coordonnées ou les paires clé-valeur dans un dictionnaire sont de bons exemples de structures.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. L’utilisation de structures plutôt que de classes pour les petites structures de données peut faire une grande différence dans le nombre d’allocations de mémoire effectuées par une application.The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. Par exemple, le programme suivant crée et initialise un tableau de 100 points.For example, the following program creates and initializes an array of 100 points. Avec Point implémenté en tant que classe, 101 objets séparés sont instanciés : un pour le tableau et un pour chacun des 100 éléments.With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Test
{
    static void Main() {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
    }
}

Une alternative consiste à faire Point un struct.An alternative is to make Point a struct.

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Maintenant, un seul objet est instancié, celui du tableau, et les instances Point sont stockées à la suite dans le tableau.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Vous appelez les constructeurs de struct avec l’opérateur new, mais cela n’implique pas que de la mémoire soit allouée.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Au lieu d’allouer dynamiquement un objet et de renvoyer une référence à cet objet, un constructeur de struct retourne simplement la valeur du struct (généralement dans un emplacement temporaire sur la pile), et cette valeur est ensuite copiée si nécessaire.Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

Avec les classes, deux variables peuvent faire référence au même objet et, par conséquent, les opérations sur une variable peuvent affecter le même objet référencé par l'autre variable.With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Avec les structs, les variables disposent chacune de leur propre copie des données, et il n’est pas possible pour les opérations sur une d’affecter les autres.With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Par exemple, la sortie produite par le fragment de code suivant varie selon que Point est une classe ou un struct.For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Si Point est une classe, la sortie est 20 car a et b référencent le même objet.If Point is a class, the output is 20 because a and b reference the same object. Si Point est un struct, la sortie est 10 , car l’affectation de a à b crée une copie de la valeur, et cette copie n’est pas affectée par l’assignation consécutive de a.x.If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

L’exemple précédent illustre deux des limitations des structs.The previous example highlights two of the limitations of structs. Tout d’abord, la copie d’un struct entier est généralement moins efficace que la copie d’une référence d’objet, aussi le passage de paramètres d’affectation et de valeur peut être plus coûteux avec les structures qu’avec les types référence.First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. Ensuite, à l’exception des paramètres ref et out, il n’est pas possible de créer des références aux structures, ce qui rend leur utilisation impossible dans un certain nombre de situations.Second, except for ref and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.

TableauxArrays

Un tableau est une structure de données qui contient un certain nombre de variables qui sont accessibles par des indices calculés.An array is a data structure that contains a number of variables that are accessed through computed indices. Les variables contenues dans un tableau, également appelé éléments du tableau, sont tous du même type, et ce type est appelé type d’élément du tableau.The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

Les types tableau sont des types référence, et la déclaration d’une variable tableau réserve simplement un espace pour une référence à une instance de tableau.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Instances de tableau réelles sont créées dynamiquement au moment de l’exécution à l’aide du new opérateur.Actual array instances are created dynamically at run-time using the new operator. Le new opération spécifie la longueur de la nouvelle instance de tableau, qui est ensuite fixée pour la durée de vie de l’instance.The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Les indices des éléments d’un tableau vont de 0 à Length - 1.The indices of the elements of an array range from 0 to Length - 1. L’opérateur new initialise automatiquement les éléments d’un tableau à leur valeur par défaut, c'est-à-dire, par exemple, zéro pour tous les types numériques et null pour tous les types référence.The new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

L’exemple suivant crée un tableau de int éléments, initialise le tableau et imprime le contenu du tableau.The following example creates an array of int elements, initializes the array, and prints out the contents of the array.

using System;

class Test
{
    static void Main() {
        int[] a = new int[10];
        for (int i = 0; i < a.Length; i++) {
            a[i] = i * i;
        }
        for (int i = 0; i < a.Length; i++) {
            Console.WriteLine("a[{0}] = {1}", i, a[i]);
        }
    }
}

Cet exemple crée et utilise un tableau unidimensionnel.This example creates and operates on a single-dimensional array. C# prend également en charge les tableaux multidimensionnels.C# also supports multi-dimensional arrays. Le nombre de dimensions d’un type tableau, également appelé rang du type tableau, est de un plus le nombre de virgules entre les crochets du type tableau.The number of dimensions of an array type, also known as the rank of the array type, is one plus the number of commas written between the square brackets of the array type. L’exemple suivant alloue un tableau tridimensionnel, une dimension et un à deux dimensions.The following example allocates a one-dimensional, a two-dimensional, and a three-dimensional array.

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

Le tableau a1 contient 10 éléments, le tableau a2 en contient 50 (10 x 5) et le tableau a3 en contient 100 (10 × 5 × 2).The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

Le type d’élément d’un tableau peut être de n’importe quel type, y compris un type tableau.The element type of an array can be any type, including an array type. Un tableau avec des éléments d’un type tableau est parfois appelé un tableau en escalier, car les longueurs des tableaux d’éléments ne sont pas nécessairement pas les mêmes.An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays do not all have to be the same. L’exemple suivant alloue un tableau de tableaux de int :The following example allocates an array of arrays of int:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

La première ligne crée un tableau avec trois éléments, chacun de type int[] et chacun avec une valeur initiale de null.The first line creates an array with three elements, each of type int[] and each with an initial value of null. Les lignes suivantes initialisent ensuite les trois éléments avec des références aux instances individuelles de tableau de longueur variable.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

Le new opérateur autorise les valeurs initiales des éléments du tableau en utilisant un initialiseur de tableau, qui est une liste d’expressions écrites entre les délimiteurs { et }.The new operator permits the initial values of the array elements to be specified using an array initializer, which is a list of expressions written between the delimiters { and }. L’exemple suivant alloue et initialise un int[] avec trois éléments.The following example allocates and initializes an int[] with three elements.

int[] a = new int[] {1, 2, 3};

Notez que la longueur du tableau est déduite à partir du nombre d’expressions entre { et }.Note that the length of the array is inferred from the number of expressions between { and }. Les déclarations locales des champs et variables peuvent être abrégées davantage afin de ne pas avoir à redéclarer le type tableau.Local variable and field declarations can be shortened further such that the array type does not have to be restated.

int[] a = {1, 2, 3};

Les deux exemples précédents sont équivalents à ce qui suit :Both of the previous examples are equivalent to the following:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

InterfacesInterfaces

Une interface définit un contrat qui peut être implémenté par des classes et structures.An interface defines a contract that can be implemented by classes and structs. Une interface peut contenir des méthodes, des propriétés, des événements et des indexeurs.An interface can contain methods, properties, events, and indexers. Une interface ne fournit pas les implémentations des membres qu’elle définit, elle indique simplement les membres qui doivent être fournis par les classes ou les structs qui implémentent l’interface.An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

Les interfaces peuvent utiliser l’héritage multiple.Interfaces may employ multiple inheritance. Dans l’exemple suivant, l’interface IComboBox hérite à la fois de ITextBox et IListBox.In the following example, the interface IComboBox inherits from both ITextBox and IListBox.

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

Les classes et les structs peuvent implémenter plusieurs interfaces.Classes and structs can implement multiple interfaces. Dans l’exemple suivant, la classe EditBox implémente à la fois IControl et IDataBound.In the following example, the class EditBox implements both IControl and IDataBound.

interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox: IControl, IDataBound
{
    public void Paint() {...}
    public void Bind(Binder b) {...}
}

Lorsqu’une classe ou un struct implémente une interface spécifique, les instances de cette classe ou struct peuvent être converties implicitement en ce type d’interface.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. Exemple :For example

EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

Si une instance n’est pas connue pour implémenter une interface donnée de façon statique, des casts de type dynamiques peuvent être utilisés.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Par exemple, les instructions suivantes utilisent des casts de type dynamique pour obtenir d’un objet IControl et IDataBound implémentations d’interface.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Étant donné que le type réel de l’objet est EditBox, les casts réussissent.Because the actual type of the object is EditBox, the casts succeed.

object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

Dans le précédent EditBox (classe), le Paint méthode à partir de la IControl interface et le Bind méthode à partir de la IDataBound interface sont implémentées à l’aide de public membres.In the previous EditBox class, the Paint method from the IControl interface and the Bind method from the IDataBound interface are implemented using public members. C# prend également en charge implémentations de membres d’interface explicite, à l’aide de laquelle la classe ou struct permettre éviter d’effectuer les membres public.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Une implémentation de membre d’interface explicite est écrite à l’aide du nom de membre d’interface qualifié complet.An explicit interface member implementation is written using the fully qualified interface member name. Par exemple, la classe EditBox peut implémenter les méthodes IControl.Paint et IDataBound.Bind à l’aide des implémentations de membres d’interface explicites, comme suit.For example, the EditBox class could implement the IControl.Paint and IDataBound.Bind methods using explicit interface member implementations as follows.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}

Les membres d’interface explicites sont accessibles uniquement via le type interface.Explicit interface members can only be accessed via the interface type. Par exemple, l’implémentation de IControl.Paint fournie par la précédente EditBox classe ne peut être appelée en convertissant d’abord en le EditBox font référence à la IControl type d’interface.For example, the implementation of IControl.Paint provided by the previous EditBox class can only be invoked by first converting the EditBox reference to the IControl interface type.

EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok

EnumsEnums

Un type enum est un type valeur distinct avec un ensemble de constantes nommées.An enum type is a distinct value type with a set of named constants. L’exemple suivant déclare et utilise un type enum nommé Color avec trois valeurs de constante, Red, Green, et Blue.The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

class Test
{
    static void PrintColor(Color color) {
        switch (color) {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
            case Color.Blue:
                Console.WriteLine("Blue");
                break;
            default:
                Console.WriteLine("Unknown color");
                break;
        }
    }

    static void Main() {
        Color c = Color.Red;
        PrintColor(c);
        PrintColor(Color.Blue);
    }
}

Chaque type énumération a un type intégral appelé le type sous-jacent du type enum.Each enum type has a corresponding integral type called the underlying type of the enum type. Un type enum qui ne déclare pas explicitement un type sous-jacent a un type sous-jacent de int.An enum type that does not explicitly declare an underlying type has an underlying type of int. Un type enum le format de stockage et la plage de valeurs possibles sont déterminés par son type sous-jacent.An enum type's storage format and range of possible values are determined by its underlying type. L’ensemble de valeurs qui peut prendre un type enum n’est pas limité par ses membres enum.The set of values that an enum type can take on is not limited by its enum members. En particulier, n’importe quelle valeur du type sous-jacent d’une énumération peut être casté en type enum et est une valeur valide distincte de ce type enum.In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

L’exemple suivant déclare un type enum nommé Alignment avec un type sous-jacent de sbyte.The following example declares an enum type named Alignment with an underlying type of sbyte.

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}

Comme le montre l’exemple précédent, une déclaration de membre enum peut inclure une expression constante qui spécifie la valeur du membre.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. La valeur de constante pour chaque membre enum doit être dans la plage du type sous-jacent de l’enum.The constant value for each enum member must be in the range of the underlying type of the enum. Lorsqu’une déclaration de membre enum ne spécifie pas explicitement une valeur, le membre reçoit la valeur zéro (s’il est le premier membre dans le type enum) ou la valeur du membre enum qui précède plus un.When an enum member declaration does not explicitly specify a value, the member is given the value zero (if it is the first member in the enum type) or the value of the textually preceding enum member plus one.

Valeurs d’énumération peuvent être converties en valeurs intégrales et inversement à l’aide de casts de type.Enum values can be converted to integral values and vice versa using type casts. Exemple :For example

int i = (int)Color.Blue;        // int i = 2;
Color c = (Color)2;             // Color c = Color.Blue;

La valeur par défaut de tout type enum est la valeur intégrale de zéro convertie vers le type enum.The default value of any enum type is the integral value zero converted to the enum type. Dans les cas où les variables sont initialisées automatiquement à une valeur par défaut, il s’agit de la valeur donnée aux variables des types enum.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Afin que la valeur par défaut d’un type enum soit disponible, le littéral 0 convertit implicitement en un type enum.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. Ce qui suit est donc autorisé.Thus, the following is permitted.

Color c = 0;

DéléguésDelegates

Un type délégué représente des références aux méthodes avec une liste de paramètres et un type de retour particuliers.A delegate type represents references to methods with a particular parameter list and return type. Les délégués permettent de traiter les méthodes en tant qu’entités qui peuvent être affectées à des variables et passées comme paramètres.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Les délégués sont similaires au concept de pointeurs de fonction dans d’autres langages, mais contrairement aux pointeurs de fonction, les délégués sont orientés objet et de type sécurisé.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

L’exemple suivant déclare et utilise un type délégué nommé Function.The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

    public Multiplier(double factor) {
        this.factor = factor;
    }

    public double Multiply(double x) {
        return x * factor;
    }
}

class Test
{
    static double Square(double x) {
        return x * x;
    }

    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void Main() {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Une instance du type délégué Function peut faire référence à toute méthode qui accepte un argument double et retourne une valeur double.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Le Apply méthode s’applique une donnée Function aux éléments d’un double[], qui retourne un double[] avec les résultats.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Dans la méthode Main, Apply sert à appliquer trois fonctions différentes à un double[].In the Main method, Apply is used to apply three different functions to a double[].

Un délégué peut faire référence à une méthode statique (comme Square ou Math.Sin dans l’exemple précédent) ou à une méthode d’instance (comme m.Multiply dans l’exemple précédent).A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). Un délégué qui référence une méthode d’instance référence aussi un objet particulier, et quand la méthode d’instance est appelée via le délégué, cet objet devient this dans l’appel.A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

Les délégués peuvent également être créés à l’aide de fonctions anonymes, qui sont des « méthodes inline » créées à la volée.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Les fonctions anonymes peuvent voir les variables locales des méthodes qui l’entourent.Anonymous functions can see the local variables of the surrounding methods. Par conséquent, l’exemple de multiplicateur ci-dessus peut être écrit plus facilement sans utiliser un Multiplier classe :Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

Une propriété intéressante et utile d’un délégué est qu’il ne connaît pas la classe de la méthode qu’il référence, et cela lui est égal. Tout ce qui importe est que la méthode référencée ait les mêmes paramètres et type de retour que le délégué.An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.

AttributsAttributes

Les types, membres et autres entités d’un programme C# prennent en charge les modificateurs qui contrôlent certains aspects de leur comportement.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. Par exemple, l’accessibilité d’une méthode est contrôlée à l’aide des modificateurs public, protected, internal et private.For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C# généralise cette fonctionnalité pour que les types d’informations déclaratives définis par l’utilisateur puissent être associés aux entités de programme et récupérés au moment de l’exécution.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Les programmes spécifient ces informations déclaratives supplémentaires en définissant et en utilisant les attributs.Programs specify this additional declarative information by defining and using attributes.

L’exemple suivant déclare un attribut HelpAttribute qui peut être placé sur des entités de programme pour fournir des liens vers leur documentation associée.The following example declares a HelpAttribute attribute that can be placed on program entities to provide links to their associated documentation.

using System;

public class HelpAttribute: Attribute
{
    string url;
    string topic;

    public HelpAttribute(string url) {
        this.url = url;
    }

    public string Url {
        get { return url; }
    }

    public string Topic {
        get { return topic; }
        set { topic = value; }
    }
}

Toutes les classes d’attributs dérivent le System.Attribute fourni par le .NET Framework de classe de base.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Les attributs peuvent être appliqués en donnant leur nom, ainsi que les éventuels arguments, à l’intérieur de crochets juste avant la déclaration associée.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Si le nom d’un attribut se termine par Attribute, cette partie du nom peut être omise lorsque l’attribut est référencé.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. Par exemple, l’attribut HelpAttribute peut être utilisé comme suit.For example, the HelpAttribute attribute can be used as follows.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

Cet exemple attache un HelpAttribute à la Widget classe et l’autre HelpAttribute à la Display méthode dans la classe.This example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. Les constructeurs publics d’une classe d’attributs contrôlent les informations qui doivent être fournies lorsque l’attribut est joint à une entité de programme.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Des informations supplémentaires peuvent être fournies en référençant les propriétés en lecture-écriture publiques de la classe d’attributs (comme la référence à la propriété Topic, précédemment).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

L’exemple suivant montre comment les informations d’attribut pour une entité de programme donné peuvent être récupérées au moment de l’exécution à l’aide de la réflexion.The following example shows how attribute information for a given program entity can be retrieved at run-time using reflection.

using System;
using System.Reflection;

class Test
{
    static void ShowHelp(MemberInfo member) {
        HelpAttribute a = Attribute.GetCustomAttribute(member,
            typeof(HelpAttribute)) as HelpAttribute;
        if (a == null) {
            Console.WriteLine("No help for {0}", member);
        }
        else {
            Console.WriteLine("Help for {0}:", member);
            Console.WriteLine("  Url={0}, Topic={1}", a.Url, a.Topic);
        }
    }

    static void Main() {
        ShowHelp(typeof(Widget));
        ShowHelp(typeof(Widget).GetMethod("Display"));
    }
}

Lorsqu’un attribut particulier est demandé par réflexion, le constructeur de la classe d’attributs est appelé avec les informations fournies dans la source du programme, et l’instance d’attribut qui en résulte est retournée.When a particular attribute is requested through reflection, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. Si des informations supplémentaires ont été fournies via les propriétés, ces propriétés sont définies sur les valeurs données avant que le renvoi de l’instance de l’attribut.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.