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 familiarisé avec les programmeurs 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 standardisé par ECMA International en tant que * norme ECMA-334 _ et par ISO/IEC comme _ iso/IEC 23270 standard.C# is standardized by ECMA International as the ECMA-334 _ standard and by ISO/IEC as the _ ISO/IEC 23270 standard. Le 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 pour prendre en charge directement ces concepts, en faisant de C# un langage très naturel dans lequel 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 C# aident à la construction d’applications robustes et durables : garbage collection _ récupère automatiquement la mémoire occupée par les objets inutilisés ; la _gestion des exceptions_ fournit une approche structurée et extensible de la détection et de la récupération des erreurs ; la conception de _ type-safe du langage rend impossible la lecture des variables non initialisées, l’indexation des tableaux au-delà de leurs limites ou l’exécution de conversions de type non vérifiées.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 d’une manière compatible, l’accent est mis sur le contrôle de version dans la conception de c#.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. Les aspects de la conception de C# qui ont été directement influencés par les considérations relatives à la gestion des versions incluent les virtual
override
modificateurs et séparés, les règles de résolution de surcharge de méthode et la prise en charge des déclarations de membres d’interface explicites.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 ultérieurs décrivent les règles et les exceptions selon une méthode orientée détails et parfois mathématique, ce chapitre s’efforce de clarifier et de concision au détriment de l’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 facilitera l’écriture de programmes précoces et la lecture des chapitres ultérieurs.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 commande.Assuming 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
qui produit un assembly exécutable nommé hello.exe
.which produces an executable assembly named hello.exe
. La sortie produite par cette application lorsqu’elle est exécutée estThe 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
. La 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 automatiquement référencées 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 de bibliothèque Runtime distincte.Note that C# itself does not have a separate runtime library. Au lieu de cela, le .NET Framework est la bibliothèque Runtime de C#.Instead, the .NET Framework is the runtime library of C#.
Structure du programmeProgram structure
Les concepts clés de l’organisation en C# sont *Programs, 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. Les assemblys ont généralement l’extension de fichier .exe
ou .dll
, selon qu’ils implémentent des applications ou _ Libraries *.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 d’instructions de langage intermédiaire _ (il) et des informations symboliques sous la forme _ Metadata *.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é, l' acme.dll
assembly peut être référencé à l’aide de l’option du compilateur /r
: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# : *types valeur _ et _ types référence *.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).
Les types valeur de C# sont encore divisés en types simples _, _types ENUM_, types _struct_ et _types Nullable_, et les types référence de c# sont divisés en _types classe_, _types interface_, _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 du système de type de C#.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 , long Signed integral: sbyte , short , int , long |
Entier non signé : byte , ushort , uint , ulong Unsigned integral: byte , ushort , uint , ulong |
||
Caractères Unicode : char Unicode characters: char |
||
Virgule flottante IEEE : float , double IEEE floating point: float , double |
||
Décimale haute précision :decimal High-precision decimal: decimal |
||
Booléen : bool Boolean: 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 null Extensions of all other value types with a null value |
|
Types référenceReference types | Types de classeClass types | Classe de base fondamentale de tous les autres types : object Ultimate base class of all other types: object |
Chaînes Unicode : string Unicode 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 de la forme, 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 types à virgule flottante, float
et double
, sont représentés à l’aide des formats IEEE 754 simple précision et double précision 64 bits 32.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.
Le type de C# bool
est utilisé pour représenter des valeurs booléennes, qui sont des valeurs 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 les types numériques de C#.The following table summarizes C#'s numeric types.
CatégorieCategory | BitsBits | TypeType | Plage/précisionRange/Precision |
---|---|---|---|
Entier signéSigned integral | 88 | sbyte |
-128... 127-128...127 |
1616 | short |
-32768... 32, 767-32,768...32,767 | |
3232 | int |
-2147483648... 2, 147, 483, 647-2,147,483,648...2,147,483,647 | |
6464 | long |
-9223372036854775808... 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 à 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, précision de 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 des catégories de types C# sont définissables par l’utilisateur : types classe, types struct, types interface, types ENUM et 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 des données membres (champs) et des fonctions membres (méthodes, propriétés et autres).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 semblable à 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, les 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 interface définit un contrat comme un jeu nommé de membres de fonction publics.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 des membres de la fonction 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 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.
Les types de classe, de struct, d’interface et de délégué prennent tous en charge les génériques, dans lesquels ils 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 enum a un type sous-jacent, qui doit être l’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 le même que 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 à deux dimensions 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
.
Les types Nullable n’ont pas besoin d’ê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 valeur n’acceptant pas les valeurs null T
, il existe 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
.
Le système de type C# est unifié de telle façon 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
. Les valeurs des types valeur sont traitées comme des objets en effectuant des opérations *boxing _ et _ *unboxing**.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 « Box », 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, lorsqu’une 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 zone du type valeur correct et, si la vérification est réussie, 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.
Le système de type unifié de C# 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 a un type qui détermine les valeurs qui peuvent ê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 référence ou une référence à une valeur boxed de n’importe quel type 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 de 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 déléguéA null reference or a reference to an instance of that delegate type |
ExpressionsExpressions
Les expressions _ sont construites à partir 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.
Lorsqu’une expression contient plusieurs opérateurs, le *précédence _ 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 les opérateurs de C#, en répertoriant les catégories d’opérateurs par ordre de priorité, de la plus élevée à la plus faible.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Les opérateurs d’une même catégorie ont une priorité identique.Operators in the same category have equal precedence.
CatégorieCategory | ExpressionExpression | DescriptionDescription |
---|---|---|
PrincipalPrimary | 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 T Obtain 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 T Obtain 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 T Explicitly convert x to type T |
|
await x |
Attendre de façon asynchrone la fin de x Asynchronously wait for x to complete |
|
MultiplicatifMultiplicative | x * y |
MultiplicationMultiplication |
x / y |
DivisionDivision | |
x % y |
ResteRemainder | |
AdditiveAdditive | 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 T Return x typed as T , or null if x is not a T |
|
ÉgalitéEquality | x == y |
Égal àEqual |
x != y |
Différent deNot equal | |
ET 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 |
OU logiqueLogical OR | x | y |
Opération de bits entière OR, Boolean logique ORInteger bitwise OR, boolean logical OR |
AND conditionnelConditional AND | x && y |
Évalue y uniquement si x est true Evaluates y only if x is true |
OR conditionnelConditional OR | x || y |
Évalue y uniquement si x est false Evaluates 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 |
Logique conditionnelleConditional | x ? y : z |
Prend la valeur y si x est true , z si x est false Evaluates y if x is true , z if x is false |
Attribution ou fonction anonymeAssignment or anonymous function | x = y |
AffectationAssignment |
x op= y |
Assignation composée ; les 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. Les expressions qui peuvent être utilisées comme instructions incluent les appels de méthode, les allocations d’objets à l’aide de l' new
opérateur, les assignations utilisant =
et les opérateurs d’assignation composée, les opérations d’incrémentation et de décrémentation à l’aide des ++
--
opérateurs et et des 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.
Les instructions d’itération sont utilisées pour exécuter une instruction incorporée de façon répété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.
Les checked
unchecked
instructions et sont utilisées pour contrôler le contexte de contrôle de dépassement de capacité pour les opérations arithmétiques de type intégral et les conversions.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
}
if
gestionif
statement
static void Main(string[] args) {
if (args.Length == 0) {
Console.WriteLine("No arguments");
}
else {
Console.WriteLine("One or more arguments");
}
}
switch
gestionswitch
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;
}
}
while
gestionwhile
statement
static void Main(string[] args) {
int i = 0;
while (i < args.Length) {
Console.WriteLine(args[i]);
i++;
}
}
do
gestiondo
statement
static void Main() {
string s;
do {
s = Console.ReadLine();
if (s != null) Console.WriteLine(s);
} while (s != null);
}
for
gestionfor
statement
static void Main(string[] args) {
for (int i = 0; i < args.Length; i++) {
Console.WriteLine(args[i]);
}
}
foreach
gestionforeach
statement
static void Main(string[] args) {
foreach (string s in args) {
Console.WriteLine(s);
}
}
break
gestionbreak
statement
static void Main() {
while (true) {
string s = Console.ReadLine();
if (s == null) break;
Console.WriteLine(s);
}
}
continue
gestioncontinue
statement
static void Main(string[] args) {
for (int i = 0; i < args.Length; i++) {
if (args[i].StartsWith("/")) continue;
Console.WriteLine(args[i]);
}
}
goto
gestiongoto
statement
static void Main(string[] args) {
int i = 0;
goto check;
loop:
Console.WriteLine(args[i++]);
check:
if (i < args.Length) goto loop;
}
return
gestionreturn
statement
static int Add(int a, int b) {
return a + b;
}
static void Main() {
Console.WriteLine(Add(1, 2));
return;
}
yield
gestionyield
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``try
instructions etthrow
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``unchecked
instructions etchecked
and unchecked
statements
static void Main() {
int i = int.MaxValue;
checked {
Console.WriteLine(i + 1); // Exception
}
unchecked {
Console.WriteLine(i + 1); // Overflow
}
}
lock
gestionlock
statement
class Account
{
decimal balance;
public void Withdraw(decimal amount) {
lock (this) {
if (amount > balance) {
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
using
gestionusing
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 _ sont les types de C# les plus fondamentaux.*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 _ 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 stockent les références à ces objets dans 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 récupérée lorsque l’objet n’est plus utilisé.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 *membres statiques _ ou _ *membres de l’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 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. Celles-ci sont récapitulées dans le tableau ci-dessous.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 ensuite être utilisés dans le corps des déclarations de classe pour définir les membres de la classe.The type parameters can then 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 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é un 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 des constructeurs statiques, et des destructeurs de la 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. L’assignation à un readonly
champ ne peut se produire que 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 par le biais de 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.
Les méthodes ont une liste (éventuellement vide) de *Parameters, 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. Le type de retour d’une méthode est void
s’il ne retourne pas de 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. Les Write
WriteLine
méthodes et de la System.Console
classe sont de bons exemples d’utilisation des tableaux de paramètres.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
Le 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 qui retourne des void
instructions non-, return
doit 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 une 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 static
modificateur est une 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 comprend un virtual
modificateur, la méthode est dite « *méthode virtuelle _ ».When an instance method declaration includes a virtual
modifier, the method is said to be a *virtual method _. Si aucun virtual
modificateur n’est présent, la méthode est dite « _ » non virtuelle* *.When no virtual
modifier is present, the method is said to be a _*non-virtual method**.
Quand une méthode virtuelle est appelée, le *type au moment de l’exécution _ de l’instance pour laquelle cet appel se produit détermine l’implémentation de méthode réelle à 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 virtuel, le _ type au moment 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 comprend un override
modificateur, la méthode substitue une méthode virtuelle héritée avec 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.
Une méthode abstraite 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 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 est similaire à, mais à ne pas confondre avec les types d’arborescence d’expression introduits dans les types d’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 un Hashtable
qui contient des noms de variables (comme clés des entrées) et des valeurs (comme 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). La Evaluate
méthode est une méthode abstraite virtuelle, ce qui signifie que les classes dérivées non abstraites doivent être substituées 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. L' VariableReference
implémentation de A recherche le nom de variable dans la Hashtable 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 méthode *surcharge _ permet à plusieurs méthodes dans la même classe d’avoir le même nom, à condition qu’elles aient 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 d’une méthode surchargée, le compilateur utilise _ Overload Resolution* 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 genres de fonctions membres pris en charge par C# : les constructeurs, les propriétés, les indexeurs, les événements, les 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 illustre une classe générique appelée List<T>
, qui implémente une liste d’objets pouvant être augmentée.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 _ static* est un membre qui implémente les actions requises pour initialiser une classe lorsqu’elle est chargée pour la première fois.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.
Les 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
*Properties _ 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 leurs 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, sauf que la déclaration se termine par un get
accesseur et/ou un set
accesseur écrit entre les délimiteurs {
et }
au lieu de se terminer 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 a uniquement un get
accesseur est une propriété en lecture seule, et une 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 de la cible d’une assignation, lorsqu’une propriété est référencée dans une expression, l' 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 comme cible d’une assignation ou comme opérande de ++
ou --
, l' 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. Les propriétés statiques sont déclarées avec le static
modificateur, et les propriétés d’instance sont déclarées sans lui.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
, suivi d’une liste de paramètres écrits 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. Par exempleFor 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, sauf que la déclaration comprend un event
mot clé et que le type doit ê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 descripteur d’événement n’est présent, 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. L' Changed
événement est déclenché par la OnChanged
méthode virtuelle, qui vérifie d’abord 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 définissent l’égalité de deux List<T>
instances en comparant chacun des objets 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 pendant garbage collection.The destructor for an instance is invoked automatically during garbage collection.
Le garbage collector est autorisé à atteindre une grande latitude en déterminant 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 du destructeur n’est pas déterministe et les destructeurs 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, les classes doivent implémenter des destructeurs uniquement quand aucune autre solution n’est possible.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.
StructuresStructs
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 à créer 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 qu’il Point
s’agit d’une classe ou d’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
due à a
et b
référence 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
due au fait que l’assignation de a
à b
crée une copie de la valeur et que cette copie n’est pas affectée par l’assignation suivante à 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 accessibles par le biais d’index 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ées *éléments* du tableau, sont toutes 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. Les instances de tableau réelles sont créées dynamiquement au moment de l’exécution à l’aide de l' new
opérateur.Actual array instances are created dynamically at run-time using the new
operator. L' new
opération spécifie la longueur de la nouvelle instance de tableau, qui est ensuite résolue 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 opère sur 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é _ Rank* du type tableau, est un plus le nombre de virgules écrites 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 unidimensionnel, à deux dimensions et à trois 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.
L' new
opérateur permet de spécifier les valeurs initiales des éléments du tableau à l’aide d’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 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. Par exempleFor 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 IControl
les implémentations d’interface et d’objet IDataBound
.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 sont correctement exécutés.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 la EditBox
classe précédente, la Paint
méthode de l' IControl
interface et la Bind
méthode de l' 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 les implémentations de membres d’interface explicites, à l’aide desquelles la classe ou le struct peuvent éviter de créer 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 EditBox
classe précédente ne peut être appelée qu’en convertissant d’abord la EditBox
référence au 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
ÉnumérationsEnums
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 constantes, 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 enum a un type intégral correspondant 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
. Le format de stockage d’un type enum 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 qu’un type enum peut utiliser 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, toute valeur du type sous-jacent d’une énumération peut être convertie 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 indiqué dans 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 comprise 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 de valeur, le membre reçoit la valeur zéro (s’il s’agit du premier membre du type enum) ou la valeur du membre enum qui précède textuel 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.
Les valeurs enum peuvent être converties en valeurs intégrales et vice versa à l’aide de casts de type.Enum values can be converted to integral values and vice versa using type casts. Par exempleFor example
int i = (int)Color.Blue; // int i = 2;
Color c = (Color)2; // Color c = Color.Blue;
La valeur par défaut d’un type enum est la valeur intégrale zéro convertie en 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 automatiquement initialisées à une valeur par défaut, il s’agit de la valeur donnée aux variables de types ENUM.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Pour que la valeur par défaut d’un type enum soit facilement 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. La Apply
méthode applique un donné Function
aux éléments d’un double[]
, en retournant 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. Ainsi, l’exemple de multiplicateur ci-dessus peut être écrit plus facilement sans utiliser une 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 de la System.Attribute
classe de base fournie par l' .NET Framework.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 un 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 récupérer des informations d’attribut pour une entité de programme donnée 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.