Concepts de baseBasic concepts

Démarrage de l'applicationApplication Startup

Un assembly qui a un point d’entrée est appelé application.An assembly that has an entry point is called an application. Lorsqu’une application est exécutée, un nouveau domaine d’application est créé.When an application is run, a new application domain is created. Plusieurs instanciations différentes d’une application peuvent exister sur le même ordinateur en même temps et chacune possède son propre domaine d’application.Several different instantiations of an application may exist on the same machine at the same time, and each has its own application domain.

Un domaine d’application permet l’isolation d’applications en jouant le rôle d’un conteneur pour l’état de l’application.An application domain enables application isolation by acting as a container for application state. Un domaine d’application agit comme un conteneur et une limite pour les types définis dans l’application et les bibliothèques de classes qu’il utilise.An application domain acts as a container and boundary for the types defined in the application and the class libraries it uses. Les types chargés dans un domaine d’application sont différents du même type chargé dans un autre domaine d’application, et les instances d’objets ne sont pas directement partagées entre les domaines d’application.Types loaded into one application domain are distinct from the same type loaded into another application domain, and instances of objects are not directly shared between application domains. Par exemple, chaque domaine d’application possède sa propre copie de variables statiques pour ces types, et un constructeur statique pour un type est exécuté au plus une fois par domaine d’application.For instance, each application domain has its own copy of static variables for these types, and a static constructor for a type is run at most once per application domain. Les implémentations sont gratuites pour fournir une stratégie ou des mécanismes spécifiques à l’implémentation pour la création et la destruction de domaines d’application.Implementations are free to provide implementation-specific policy or mechanisms for the creation and destruction of application domains.

Le démarrage de l' application se produit lorsque l’environnement d’exécution appelle une méthode désignée, appelée point d’entrée de l’application.Application startup occurs when the execution environment calls a designated method, which is referred to as the application's entry point. Cette méthode de point d’entrée est toujours nommée Mainet peut avoir l’une des signatures suivantes :This entry point method is always named Main, and can have one of the following signatures:

static void Main() {...}

static void Main(string[] args) {...}

static int Main() {...}

static int Main(string[] args) {...}

Comme indiqué, le point d’entrée peut éventuellement retourner une valeur int.As shown, the entry point may optionally return an int value. Cette valeur de retour est utilisée dans l’arrêt de l’application (arrêt de l'application).This return value is used in application termination (Application termination).

Le point d’entrée peut éventuellement avoir un paramètre formel.The entry point may optionally have one formal parameter. Le paramètre peut avoir n’importe quel nom, mais le type du paramètre doit être string[].The parameter may have any name, but the type of the parameter must be string[]. Si le paramètre formel est présent, l’environnement d’exécution crée et passe un argument string[] contenant les arguments de ligne de commande spécifiés au démarrage de l’application.If the formal parameter is present, the execution environment creates and passes a string[] argument containing the command-line arguments that were specified when the application was started. L’argument string[] n’est jamais null, mais peut avoir une longueur de zéro si aucun argument de ligne de commande n’a été spécifié.The string[] argument is never null, but it may have a length of zero if no command-line arguments were specified.

Étant C# donné que prend en charge la surcharge de méthode, une classe ou un struct peut contenir plusieurs définitions d’une méthode, à condition que chacune ait une signature différente.Since C# supports method overloading, a class or struct may contain multiple definitions of some method, provided each has a different signature. Toutefois, au sein d’un même programme, aucune classe ou structure ne peut contenir plusieurs méthodes appelées Main dont la définition la qualifie à utiliser comme point d’entrée de l’application.However, within a single program, no class or struct may contain more than one method called Main whose definition qualifies it to be used as an application entry point. Toutefois, d’autres versions surchargées de Main sont autorisées, à condition qu’elles aient plusieurs paramètres, ou que leur seul paramètre soit autre que le type string[].Other overloaded versions of Main are permitted, however, provided they have more than one parameter, or their only parameter is other than type string[].

Une application peut être composée de plusieurs classes ou structures.An application can be made up of multiple classes or structs. Il est possible que plus d’une de ces classes ou structures contiennent une méthode appelée Main dont la définition la qualifie à utiliser comme point d’entrée de l’application.It is possible for more than one of these classes or structs to contain a method called Main whose definition qualifies it to be used as an application entry point. Dans ce cas, un mécanisme externe (tel qu’une option du compilateur de ligne de commande) doit être utilisé pour sélectionner l’une de ces méthodes de Main comme point d’entrée.In such cases, an external mechanism (such as a command-line compiler option) must be used to select one of these Main methods as the entry point.

Dans C#, chaque méthode doit être définie en tant que membre d’une classe ou d’un struct.In C#, every method must be defined as a member of a class or struct. En règle générale, l’accessibilité déclarée (accessibilité déclarée) d’une méthode est déterminée par les modificateurs d’accès (modificateurs d’accès) spécifiés dans sa déclaration, et de la même façon, l’accessibilité déclarée d’un type est déterminée par les modificateurs d’accès spécifiés dans sa déclaration.Ordinarily, the declared accessibility (Declared accessibility) of a method is determined by the access modifiers (Access modifiers) specified in its declaration, and similarly the declared accessibility of a type is determined by the access modifiers specified in its declaration. Pour qu’une méthode donnée d’un type donné puisse être appelée, le type et le membre doivent être accessibles.In order for a given method of a given type to be callable, both the type and the member must be accessible. Toutefois, le point d’entrée de l’application est un cas particulier.However, the application entry point is a special case. Plus précisément, l’environnement d’exécution peut accéder au point d’entrée de l’application, quelle que soit l’accessibilité déclarée et indépendamment de l’accessibilité déclarée de ses déclarations de type englobant.Specifically, the execution environment can access the application's entry point regardless of its declared accessibility and regardless of the declared accessibility of its enclosing type declarations.

La méthode de point d’entrée de l’application ne peut pas figurer dans une déclaration de classe générique.The application entry point method may not be in a generic class declaration.

Dans tous les autres aspects, les méthodes de point d’entrée se comportent comme celles qui ne sont pas des points d’entrée.In all other respects, entry point methods behave like those that are not entry points.

Arrêt de l’applicationApplication termination

L’arrêt de l' application retourne le contrôle à l’environnement d’exécution.Application termination returns control to the execution environment.

Si le type de retour de la méthode de point d’entrée de l’application est int, la valeur retournée sert de code d’état d' arrêtde l’application.If the return type of the application's entry point method is int, the value returned serves as the application's termination status code. L’objectif de ce code est de permettre la communication de la réussite ou de l’échec à l’environnement d’exécution.The purpose of this code is to allow communication of success or failure to the execution environment.

Si le type de retour de la méthode de point d’entrée est void, l’atteinte de l’accolade fermante (}) qui termine cette méthode, ou l’exécution d’une instruction return qui n’a pas d’expression, entraîne un code d’état d’arrêt de 0.If the return type of the entry point method is void, reaching the right brace (}) which terminates that method, or executing a return statement that has no expression, results in a termination status code of 0.

Avant l’arrêt d’une application, les destructeurs de tous ses objets qui n’ont pas encore été récupérés par le garbage collector sont appelés, à moins que ce nettoyage ait été supprimé (par un appel à la méthode de la bibliothèque GC.SuppressFinalize, par exemple).Prior to an application's termination, destructors for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example).

DéclarationsDeclarations

Les déclarations d' C# un programme définissent les éléments constitutifs du programme.Declarations in a C# program define the constituent elements of the program. C#les programmes sont organisés à l’aide d’espaces de noms (espaces de noms), qui peuvent contenir des déclarations de type et des déclarations d’espaces de noms imbriqués.C# programs are organized using namespaces (Namespaces), which can contain type declarations and nested namespace declarations. Les déclarations de type (déclarations de type) sont utilisées pour définir des classes (classes), des structures (structs), des interfaces (interfaces), des enums (énumérations) et des délégués (délégués).Type declarations (Type declarations) are used to define classes (Classes), structs (Structs), interfaces (Interfaces), enums (Enums), and delegates (Delegates). Les genres de membres autorisés dans une déclaration de type dépendent de la forme de la déclaration de type.The kinds of members permitted in a type declaration depend on the form of the type declaration. Par exemple, les déclarations de classe peuvent contenir des déclarations pour les constantes (constantes), champs (champs), méthodes (méthodes), propriétés (Propriétés), événements (événements), indexeurs (indexeurs), opérateurs (opérateurs), constructeurs d’instance (constructeurs d’instance), constructeurs statiques (constructeurs statiques), destructeurs (destructeurs) et types imbriqués (types imbriqués).For instance, class declarations can contain declarations for constants (Constants), fields (Fields), methods (Methods), properties (Properties), events (Events), indexers (Indexers), operators (Operators), instance constructors (Instance constructors), static constructors (Static constructors), destructors (Destructors), and nested types (Nested types).

Une déclaration définit un nom dans l' espace de déclaration auquel la déclaration appartient.A declaration defines a name in the declaration space to which the declaration belongs. À l’exception des membres surchargés (signatures et surcharge), il s’agit d’une erreur au moment de la compilation d’avoir au moins deux déclarations qui introduisent des membres portant le même nom dans un espace de déclaration.Except for overloaded members (Signatures and overloading), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. Il n’est jamais possible pour un espace de déclaration de contenir différents genres de membres portant le même nom.It is never possible for a declaration space to contain different kinds of members with the same name. Par exemple, un espace de déclaration ne peut jamais contenir un champ et une méthode du même nom.For example, a declaration space can never contain a field and a method by the same name.

Il existe différents types d’espaces de déclaration, comme décrit dans l’exemple suivant.There are several different types of declaration spaces, as described in the following.

  • Dans tous les fichiers sources d’un programme, namespace_member_declarations sans namespace_declaration englobante sont membres d’un espace de déclaration combiné unique, appelé espace de déclaration globale.Within all source files of a program, namespace_member_declarations with no enclosing namespace_declaration are members of a single combined declaration space called the global declaration space.
  • Dans tous les fichiers sources d’un programme, namespace_member_declarationdans namespace_declarations qui ont le même nom d’espace de noms qualifié complet sont membres d’un espace de déclaration combiné unique.Within all source files of a program, namespace_member_declarations within namespace_declarations that have the same fully qualified namespace name are members of a single combined declaration space.
  • Chaque déclaration de classe, de struct ou d’interface crée un nouvel espace de déclaration.Each class, struct, or interface declaration creates a new declaration space. Les noms sont introduits dans cet espace de déclaration par le biais de class_member_declarations, struct_member_declarations, interface_member_declarations ou type_parameters.Names are introduced into this declaration space through class_member_declarations, struct_member_declarations, interface_member_declarations, or type_parameters. Sauf pour les déclarations de constructeur d’instance surchargé et les déclarations de constructeur statiques, une classe ou un struct ne peut pas contenir une déclaration de membre portant le même nom que la classe ou le struct.Except for overloaded instance constructor declarations and static constructor declarations, a class or struct cannot contain a member declaration with the same name as the class or struct. Une classe, un struct ou une interface autorise la déclaration de méthodes surchargées et d’indexeurs.A class, struct, or interface permits the declaration of overloaded methods and indexers. En outre, une classe ou un struct autorise la déclaration de constructeurs et d’opérateurs d’instance surchargés.Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. Par exemple, une classe, un struct ou une interface peut contenir plusieurs déclarations de méthode portant le même nom, à condition que ces déclarations de méthode diffèrent dans leur signature (signatures et surcharge).For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature (Signatures and overloading). Notez que les classes de base ne contribuent pas à l’espace de déclaration d’une classe et que les interfaces de base ne contribuent pas à l’espace de déclaration d’une interface.Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Ainsi, une classe ou une interface dérivée est autorisée à déclarer un membre portant le même nom qu’un membre hérité.Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Ce membre est dit de Masquer le membre hérité.Such a member is said to hide the inherited member.
  • Chaque déclaration Delegate crée un nouvel espace de déclaration.Each delegate declaration creates a new declaration space. Les noms sont introduits dans cet espace de déclaration via des paramètres formels (fixed_parameters et parameter_arrays) et type_parameters.Names are introduced into this declaration space through formal parameters (fixed_parameters and parameter_arrays) and type_parameters.
  • Chaque déclaration d’énumération crée un nouvel espace de déclaration.Each enumeration declaration creates a new declaration space. Les noms sont introduits dans cet espace de déclaration par le biais de enum_member_declarations.Names are introduced into this declaration space through enum_member_declarations.
  • Chaque déclaration de méthode, déclaration d’indexeur, déclaration d’opérateur, déclaration de constructeur d’instance et fonction anonyme crée un espace de déclaration appelé espace de déclaration de variable locale.Each method declaration, indexer declaration, operator declaration, instance constructor declaration and anonymous function creates a new declaration space called a local variable declaration space. Les noms sont introduits dans cet espace de déclaration via des paramètres formels (fixed_parameters et parameter_arrays) et type_parameters.Names are introduced into this declaration space through formal parameters (fixed_parameters and parameter_arrays) and type_parameters. Le corps de la fonction membre ou de la fonction anonyme, le cas échéant, est considéré comme imbriqué dans l’espace de déclaration de la variable locale.The body of the function member or anonymous function, if any, is considered to be nested within the local variable declaration space. Il s’agit d’une erreur pour un espace de déclaration de variable locale et un espace de déclaration de variable locale imbriqué pour contenir des éléments portant le même nom.It is an error for a local variable declaration space and a nested local variable declaration space to contain elements with the same name. Ainsi, dans un espace de déclaration imbriqué, il n’est pas possible de déclarer une variable locale ou une constante portant le même nom qu’une variable locale ou une constante dans un espace de déclaration englobant.Thus, within a nested declaration space it is not possible to declare a local variable or constant with the same name as a local variable or constant in an enclosing declaration space. Il est possible que deux espaces de déclaration contiennent des éléments portant le même nom, à condition que l’espace de déclaration ne contienne pas l’autre.It is possible for two declaration spaces to contain elements with the same name as long as neither declaration space contains the other.
  • Chaque bloc ou switch_block , ainsi qu’une instruction for, foreach et using , crée un espace de déclaration de variable locale pour les variables locales et les constantes locales.Each block or switch_block , as well as a for, foreach and using statement, creates a local variable declaration space for local variables and local constants . Les noms sont introduits dans cet espace de déclaration par le biais de local_variable_declarations et local_constant_declarations.Names are introduced into this declaration space through local_variable_declarations and local_constant_declarations. Notez que les blocs qui se produisent en tant que ou dans le corps d’un membre de fonction ou d’une fonction anonyme sont imbriqués dans l’espace de déclaration de variable locale déclaré par ces fonctions pour leurs paramètres.Note that blocks that occur as or within the body of a function member or anonymous function are nested within the local variable declaration space declared by those functions for their parameters. Par conséquent, il s’agit d’une erreur d’avoir une méthode avec une variable locale et un paramètre du même nom.Thus it is an error to have e.g. a method with a local variable and a parameter of the same name.
  • Chaque bloc ou switch_block crée un espace de déclaration distinct pour les étiquettes.Each block or switch_block creates a separate declaration space for labels. Les noms sont introduits dans cet espace de déclaration par le biais de labeled_statements, et les noms sont référencés par le biais de goto_statements.Names are introduced into this declaration space through labeled_statements, and the names are referenced through goto_statements. L' espace de déclaration d’étiquette d’un bloc comprend tous les blocs imbriqués.The label declaration space of a block includes any nested blocks. Ainsi, dans un bloc imbriqué, il n’est pas possible de déclarer une étiquette portant le même nom qu’une étiquette dans un bloc englobant.Thus, within a nested block it is not possible to declare a label with the same name as a label in an enclosing block.

L’ordre textuel dans lequel les noms sont déclarés n’a généralement pas d’importance.The textual order in which names are declared is generally of no significance. En particulier, l’ordre textuel n’est pas significatif pour la déclaration et l’utilisation des espaces de noms, des constantes, des méthodes, des propriétés, des événements, des indexeurs, des opérateurs, des constructeurs d’instance, des destructeurs, des constructeurs statiques et des types.In particular, textual order is not significant for the declaration and use of namespaces, constants, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. L’ordre de déclaration est significatif des manières suivantes :Declaration order is significant in the following ways:

  • L’ordre de déclaration pour les déclarations de champ et les déclarations de variable locale détermine l’ordre dans lequel leurs initialiseurs (le cas échéant) sont exécutés.Declaration order for field declarations and local variable declarations determines the order in which their initializers (if any) are executed.
  • Les variables locales doivent être définies avant d’être utilisées (étendues).Local variables must be defined before they are used (Scopes).
  • L’ordre de déclaration pour les déclarations de membre enum (membres enum) est significatif lorsque constant_expression valeurs sont omises.Declaration order for enum member declarations (Enum members) is significant when constant_expression values are omitted.

L’espace de déclaration d’un espace de noms est « Open Closed » et deux déclarations d’espaces de noms portant le même nom qualifié complet participent au même espace de déclaration.The declaration space of a namespace is "open ended", and two namespace declarations with the same fully qualified name contribute to the same declaration space. Exemple :For example

namespace Megacorp.Data
{
    class Customer
    {
        ...
    }
}

namespace Megacorp.Data
{
    class Order
    {
        ...
    }
}

Les deux déclarations d’espaces de noms ci-dessus contribuent au même espace de déclaration, dans ce cas, en déclarant deux classes avec les noms qualifiés complets Megacorp.Data.Customer et Megacorp.Data.Order.The two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names Megacorp.Data.Customer and Megacorp.Data.Order. Étant donné que les deux déclarations contribuent au même espace de déclaration, elles auraient provoqué une erreur au moment de la compilation si chacune contient une déclaration d’une classe portant le même nom.Because the two declarations contribute to the same declaration space, it would have caused a compile-time error if each contained a declaration of a class with the same name.

Comme indiqué ci-dessus, l’espace de déclaration d’un bloc comprend tous les blocs imbriqués.As specified above, the declaration space of a block includes any nested blocks. Ainsi, dans l’exemple suivant, les méthodes F et G entraînent une erreur au moment de la compilation, car le nom i est déclaré dans le bloc externe et ne peut pas être redéclaré dans le bloc interne.Thus, in the following example, the F and G methods result in a compile-time error because the name i is declared in the outer block and cannot be redeclared in the inner block. Toutefois, les méthodes H et I sont valides, car les deux isont déclarées dans des blocs non imbriqués distincts.However, the H and I methods are valid since the two i's are declared in separate non-nested blocks.

class A
{
    void F() {
        int i = 0;
        if (true) {
            int i = 1;            
        }
    }

    void G() {
        if (true) {
            int i = 0;
        }
        int i = 1;                
    }

    void H() {
        if (true) {
            int i = 0;
        }
        if (true) {
            int i = 1;
        }
    }

    void I() {
        for (int i = 0; i < 10; i++)
            H();
        for (int i = 0; i < 10; i++)
            H();
    }
}

MembresMembers

Les espaces de noms et les types ont des membres.Namespaces and types have members. Les membres d’une entité sont généralement disponibles via l’utilisation d’un nom qualifié qui commence par une référence à l’entité, suivi d’un jeton «.», suivi du nom du membre.The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a "." token, followed by the name of the member.

Les membres d’un type sont déclarés dans la déclaration de type ou hérités de la classe de base du type.Members of a type are either declared in the type declaration or inherited from the base class of the type. Lorsqu’un type hérite d’une classe de base, tous les membres de la classe de base, à l’exception des constructeurs d’instance, des destructeurs et des constructeurs statiques, deviennent membres du type dérivé.When a type inherits from a base class, all members of the base class, except instance constructors, destructors and static constructors, become members of the derived type. L’accessibilité déclarée d’un membre de classe de base ne contrôle pas si le membre est hérité ; l’héritage s’étend à tout membre qui n’est pas un constructeur d’instance, un constructeur statique ou un destructeur.The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn't an instance constructor, static constructor, or destructor. Toutefois, un membre hérité peut ne pas être accessible dans un type dérivé, soit en raison de son accessibilité déclarée (accessibilité déclarée), soit parce qu’il est masqué par une déclaration dans le type lui-même (masquage par héritage).However, an inherited member may not be accessible in a derived type, either because of its declared accessibility (Declared accessibility) or because it is hidden by a declaration in the type itself (Hiding through inheritance).

Membres d’espace de nomsNamespace members

Les espaces de noms et les types qui n’ont pas d’espace de noms englobant sont membres de l' espace de noms global.Namespaces and types that have no enclosing namespace are members of the global namespace. Cela correspond directement aux noms déclarés dans l’espace de déclaration globale.This corresponds directly to the names declared in the global declaration space.

Les espaces de noms et les types déclarés dans un espace de noms sont membres de cet espace de noms.Namespaces and types declared within a namespace are members of that namespace. Cela correspond directement aux noms déclarés dans l’espace de déclaration de l’espace de noms.This corresponds directly to the names declared in the declaration space of the namespace.

Les espaces de noms ne présentent aucune limitation d’accès.Namespaces have no access restrictions. Il n’est pas possible de déclarer des espaces de noms privés, protégés ou internes, et les noms d’espaces de noms sont toujours accessibles publiquement.It is not possible to declare private, protected, or internal namespaces, and namespace names are always publicly accessible.

Membres de structStruct members

Les membres d’un struct sont les membres déclarés dans le struct et les membres hérités de la classe de base directe du struct System.ValueType et la classe de base indirecte object.The members of a struct are the members declared in the struct and the members inherited from the struct's direct base class System.ValueType and the indirect base class object.

Les membres d’un type simple correspondent directement aux membres du type struct dont le type est simple :The members of a simple type correspond directly to the members of the struct type aliased by the simple type:

  • Les membres de sbyte sont les membres du struct System.SByte.The members of sbyte are the members of the System.SByte struct.
  • Les membres de byte sont les membres du struct System.Byte.The members of byte are the members of the System.Byte struct.
  • Les membres de short sont les membres du struct System.Int16.The members of short are the members of the System.Int16 struct.
  • Les membres de ushort sont les membres du struct System.UInt16.The members of ushort are the members of the System.UInt16 struct.
  • Les membres de int sont les membres du struct System.Int32.The members of int are the members of the System.Int32 struct.
  • Les membres de uint sont les membres du struct System.UInt32.The members of uint are the members of the System.UInt32 struct.
  • Les membres de long sont les membres du struct System.Int64.The members of long are the members of the System.Int64 struct.
  • Les membres de ulong sont les membres du struct System.UInt64.The members of ulong are the members of the System.UInt64 struct.
  • Les membres de char sont les membres du struct System.Char.The members of char are the members of the System.Char struct.
  • Les membres de float sont les membres du struct System.Single.The members of float are the members of the System.Single struct.
  • Les membres de double sont les membres du struct System.Double.The members of double are the members of the System.Double struct.
  • Les membres de decimal sont les membres du struct System.Decimal.The members of decimal are the members of the System.Decimal struct.
  • Les membres de bool sont les membres du struct System.Boolean.The members of bool are the members of the System.Boolean struct.

Membres de l’énumérationEnumeration members

Les membres d’une énumération sont les constantes déclarées dans l’énumération et les membres hérités de la classe de base directe de l’énumération System.Enum et les classes de base indirectes System.ValueType et object.The members of an enumeration are the constants declared in the enumeration and the members inherited from the enumeration's direct base class System.Enum and the indirect base classes System.ValueType and object.

Membres de classeClass members

Les membres d’une classe sont les membres déclarés dans la classe et les membres hérités de la classe de base (à l’exception de la classe object qui n’a pas de classe de base).The members of a class are the members declared in the class and the members inherited from the base class (except for class object which has no base class). Les membres hérités de la classe de base incluent les constantes, les champs, les méthodes, les propriétés, les événements, les indexeurs, les opérateurs et les types de la classe de base, mais pas les constructeurs d’instance, les destructeurs et les constructeurs statiques de la classe de base.The members inherited from the base class include the constants, fields, methods, properties, events, indexers, operators, and types of the base class, but not the instance constructors, destructors and static constructors of the base class. Les membres de la classe de base sont hérités sans tenir compte de leur accessibilité.Base class members are inherited without regard to their accessibility.

Une déclaration de classe peut contenir des déclarations de constantes, des champs, des méthodes, des propriétés, des événements, des indexeurs, des opérateurs, des constructeurs d’instance, des destructeurs, des constructeurs statiques et des types.A class declaration may contain declarations of constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors and types.

Les membres de object et string correspondent directement aux membres des types de classe qu’ils aliasent :The members of object and string correspond directly to the members of the class types they alias:

  • Les membres de object sont les membres de la classe System.Object.The members of object are the members of the System.Object class.
  • Les membres de string sont les membres de la classe System.String.The members of string are the members of the System.String class.

Membres d’interfaceInterface members

Les membres d’une interface sont les membres déclarés dans l’interface et dans toutes les interfaces de base de l’interface.The members of an interface are the members declared in the interface and in all base interfaces of the interface. Les membres de la classe object ne sont pas des membres de toute interface (membres d’interface), strictement parlants.The members in class object are not, strictly speaking, members of any interface (Interface members). Toutefois, les membres de la classe object sont disponibles via la recherche de membres dans n’importe quel type d’interface (recherche de membre).However, the members in class object are available via member lookup in any interface type (Member lookup).

Membres du tableauArray members

Les membres d’un tableau sont les membres hérités de la classe System.Array.The members of an array are the members inherited from class System.Array.

Membres déléguésDelegate members

Les membres d’un délégué sont les membres hérités de la classe System.Delegate.The members of a delegate are the members inherited from class System.Delegate.

Accès au membreMember access

Les déclarations de membres permettent de contrôler l’accès aux membres.Declarations of members allow control over member access. L’accessibilité d’un membre est établie par l’accessibilité déclarée (accessibilité déclarée) du membre combiné avec l’accessibilité du type conteneur immédiatement, le cas échéant.The accessibility of a member is established by the declared accessibility (Declared accessibility) of the member combined with the accessibility of the immediately containing type, if any.

Lorsque l’accès à un membre particulier est autorisé, le membre est dit accessible.When access to a particular member is allowed, the member is said to be accessible. Inversement, lorsque l’accès à un membre particulier n’est pas autorisé, le membre est dit inaccessible.Conversely, when access to a particular member is disallowed, the member is said to be inaccessible. L’accès à un membre est autorisé lorsque l’emplacement du texte dans lequel l’accès a lieu est inclus dans le domaine d’accessibilité (domaines d’accessibilité) du membre.Access to a member is permitted when the textual location in which the access takes place is included in the accessibility domain (Accessibility domains) of the member.

Accessibilité déclaréeDeclared accessibility

L' accessibilité déclarée d’un membre peut être l’une des suivantes :The declared accessibility of a member can be one of the following:

  • Public, qui est sélectionné en incluant un modificateur de public dans la déclaration de membre.Public, which is selected by including a public modifier in the member declaration. La signification intuitive de public est « accès non limité ».The intuitive meaning of public is "access not limited".
  • Protégé, qui est sélectionné en incluant un modificateur de protected dans la déclaration de membre.Protected, which is selected by including a protected modifier in the member declaration. La signification intuitive de protected est « accès limité à la classe conteneur ou aux types dérivés de la classe conteneur ».The intuitive meaning of protected is "access limited to the containing class or types derived from the containing class".
  • Interne, qui est sélectionné en incluant un modificateur de internal dans la déclaration de membre.Internal, which is selected by including an internal modifier in the member declaration. La signification intuitive de internal est « accès limité à ce programme ».The intuitive meaning of internal is "access limited to this program".
  • Protected internal (c’est-à-dire protected ou Internal), qui est sélectionné en incluant à la fois un protected et un modificateur internal dans la déclaration de membre.Protected internal (meaning protected or internal), which is selected by including both a protected and an internal modifier in the member declaration. La signification intuitive de protected internal est « accès limité à ce programme ou aux types dérivés de la classe conteneur ».The intuitive meaning of protected internal is "access limited to this program or types derived from the containing class".
  • Privé, qui est sélectionné en incluant un modificateur de private dans la déclaration de membre.Private, which is selected by including a private modifier in the member declaration. La signification intuitive de private est « accès limité au type conteneur ».The intuitive meaning of private is "access limited to the containing type".

En fonction du contexte dans lequel la déclaration d’un membre a lieu, seuls certains types d’accessibilité déclarés sont autorisés.Depending on the context in which a member declaration takes place, only certain types of declared accessibility are permitted. En outre, lorsqu’une déclaration de membre n’inclut pas de modificateur d’accès, le contexte dans lequel la déclaration a lieu détermine l’accessibilité déclarée par défaut.Furthermore, when a member declaration does not include any access modifiers, the context in which the declaration takes place determines the default declared accessibility.

  • Les espaces de noms ont implicitement public l’accessibilité déclarée.Namespaces implicitly have public declared accessibility. Aucun modificateur d’accès n’est autorisé sur les déclarations d’espace de noms.No access modifiers are allowed on namespace declarations.
  • Les types déclarés dans les unités de compilation ou les espaces de noms peuvent avoir public ou internal l’accessibilité déclarée et par défaut pour internal l’accessibilité déclarée.Types declared in compilation units or namespaces can have public or internal declared accessibility and default to internal declared accessibility.
  • Les membres de classe peuvent avoir l’un des cinq types d’accessibilité déclarés et la valeur par défaut pour private l’accessibilité déclarée.Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. (Notez qu’un type déclaré en tant que membre d’une classe peut avoir l’un des cinq types d’accessibilité déclarés, alors qu’un type déclaré en tant que membre d’un espace de noms ne peut avoir que public ou internal l’accessibilité déclarée.)(Note that a type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Les membres de struct peuvent avoir public, internalou private l’accessibilité déclarée et par défaut pour private l’accessibilité déclarée, car les structs sont implicitement sealed.Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because structs are implicitly sealed. Les membres de struct introduits dans un struct (autrement dit, qui n’est pas hérité par ce struct) ne peuvent pas avoir d' protected ou protected internal l’accessibilité déclarée.Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. (Notez qu’un type déclaré en tant que membre d’un struct peut avoir public, internalou private l’accessibilité déclarée, alors qu’un type déclaré en tant que membre d’un espace de noms ne peut avoir que des public ou internal l’accessibilité déclarée.)(Note that a type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Les membres d’interface ont implicitement public l’accessibilité déclarée.Interface members implicitly have public declared accessibility. Aucun modificateur d’accès n’est autorisé sur les déclarations de membres d’interface.No access modifiers are allowed on interface member declarations.
  • Les membres de l’énumération ont implicitement public l’accessibilité déclarée.Enumeration members implicitly have public declared accessibility. Aucun modificateur d’accès n’est autorisé sur les déclarations de membre d’énumération.No access modifiers are allowed on enumeration member declarations.

Domaines d’accessibilitéAccessibility domains

Le domaine d’accessibilité d’un membre se compose des sections (éventuellement disjointes) du texte de programme dans lesquelles l’accès au membre est autorisé.The accessibility domain of a member consists of the (possibly disjoint) sections of program text in which access to the member is permitted. Dans le cadre de la définition du domaine d’accessibilité d’un membre, un membre est dit comme étant de niveau supérieur s’il n’est pas déclaré dans un type, et un membre est dit imbriqué s’il est déclaré dans un autre type.For purposes of defining the accessibility domain of a member, a member is said to be top-level if it is not declared within a type, and a member is said to be nested if it is declared within another type. En outre, le texte de programme d’un programme est défini comme tout le texte de programme contenu dans tous les fichiers sources du programme, et le texte de programme d’un type est défini comme tout le texte de programme contenu dans le type_declarations de ce type (y compris, éventuellement, les types imbriqués dans le type).Furthermore, the program text of a program is defined as all program text contained in all source files of the program, and the program text of a type is defined as all program text contained in the type_declarations of that type (including, possibly, types that are nested within the type).

Le domaine d’accessibilité d’un type prédéfini (tel que object, intou double) est illimité.The accessibility domain of a predefined type (such as object, int, or double) is unlimited.

Le domaine d’accessibilité d’un type indépendant de niveau supérieur T (types liés et indépendants) qui est déclaré dans un programme P est défini comme suit :The accessibility domain of a top-level unbound type T (Bound and unbound types) that is declared in a program P is defined as follows:

  • Si l’accessibilité déclarée de T est public, le domaine d’accessibilité de T est le texte de programme de P et tout programme qui référence P.If the declared accessibility of T is public, the accessibility domain of T is the program text of P and any program that references P.
  • Si l'accessibilité déclarée de T est internal, le domaine d'accessibilité de T correspond au texte de programme de P.If the declared accessibility of T is internal, the accessibility domain of T is the program text of P.

À partir de ces définitions, il en résulte que le domaine d’accessibilité d’un type indépendant de niveau supérieur est toujours au moins le texte de programme du programme dans lequel ce type est déclaré.From these definitions it follows that the accessibility domain of a top-level unbound type is always at least the program text of the program in which that type is declared.

Le domaine d’accessibilité d’un type construit T<A1, ..., An> est l’intersection du domaine d’accessibilité du type générique indépendant T et des domaines d’accessibilité des arguments de type A1, ..., An.The accessibility domain for a constructed type T<A1, ..., An> is the intersection of the accessibility domain of the unbound generic type T and the accessibility domains of the type arguments A1, ..., An.

Le domaine d’accessibilité d’un membre imbriqué M déclaré dans un type T dans un P de programme est défini comme suit (Notez que M lui-même peut être un type) :The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M itself may possibly be a type):

  • Si l'accessibilité déclarée de M est public, le domaine d'accessibilité de M correspond à celui de T.If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.
  • Si l’accessibilité déclarée de M est protected internal, laissez D être l’Union du texte de programme de P et le texte de programme de tout type dérivé de T, déclaré en dehors de P.If the declared accessibility of M is protected internal, let D be the union of the program text of P and the program text of any type derived from T, which is declared outside P. Le domaine d’accessibilité de M est l’intersection du domaine d’accessibilité de T avec D.The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • Si l’accessibilité déclarée de M est protected, laissez D être l’Union du texte de programme de T et le texte de programme de n’importe quel type dérivé de T.If the declared accessibility of M is protected, let D be the union of the program text of T and the program text of any type derived from T. Le domaine d’accessibilité de M est l’intersection du domaine d’accessibilité de T avec D.The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • Si l'accessibilité déclarée de M est internal, le domaine d'accessibilité de M correspond à l'intersection du domaine d'accessibilité de T avec le texte de programme de P.If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P.
  • Si l'accessibilité déclarée de M est private, le domaine d'accessibilité de M correspond au texte de programme de T.If the declared accessibility of M is private, the accessibility domain of M is the program text of T.

À partir de ces définitions, il s’ensuit que le domaine d’accessibilité d’un membre imbriqué est toujours au moins le texte de programme du type dans lequel le membre est déclaré.From these definitions it follows that the accessibility domain of a nested member is always at least the program text of the type in which the member is declared. En outre, il s’ensuit que le domaine d’accessibilité d’un membre n’est jamais plus inclusif que le domaine d’accessibilité du type dans lequel le membre est déclaré.Furthermore, it follows that the accessibility domain of a member is never more inclusive than the accessibility domain of the type in which the member is declared.

En termes intuitifs, lors de l’accès à un type ou à un membre M, les étapes suivantes sont évaluées pour s’assurer que l’accès est autorisé :In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted:

  • Premièrement, si M est déclaré dans un type (par opposition à une unité de compilation ou un espace de noms), une erreur de compilation se produit si ce type n’est pas accessible.First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible.
  • Ensuite, si M est public, l’accès est autorisé.Then, if M is public, the access is permitted.
  • Sinon, si M est protected internal, l’accès est autorisé s’il se produit dans le programme dans lequel M est déclaré, ou s’il se produit dans une classe dérivée de la classe dans laquelle M est déclaré et qui a lieu via le type de classe dérivée (accès protégé pour les membres d’instance).Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • Sinon, si M est protected, l’accès est autorisé s’il se produit dans la classe dans laquelle M est déclaré, ou s’il se produit dans une classe dérivée de la classe dans laquelle M est déclaré et qui a lieu via le type de classe dérivée (accès protégé pour les membres d’instance).Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • Sinon, si M est internal, l’accès est autorisé s’il se produit dans le programme dans lequel M est déclaré.Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared.
  • Sinon, si M est private, l’accès est autorisé s’il se produit dans le type dans lequel M est déclaré.Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared.
  • Dans le cas contraire, le type ou le membre n’est pas accessible et une erreur de compilation se produit.Otherwise, the type or member is inaccessible, and a compile-time error occurs.

Dans l’exempleIn the example

public class A
{
    public static int X;
    internal static int Y;
    private static int Z;
}

internal class B
{
    public static int X;
    internal static int Y;
    private static int Z;

    public class C
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }

    private class D
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
}

les classes et les membres ont les domaines d’accessibilité suivants :the classes and members have the following accessibility domains:

  • Le domaine d’accessibilité de A et A.X est illimité.The accessibility domain of A and A.X is unlimited.
  • Le domaine d’accessibilité de A.Y, B, B.X, B.Y, B.C, B.C.Xet B.C.Y est le texte de programme du programme conteneur.The accessibility domain of A.Y, B, B.X, B.Y, B.C, B.C.X, and B.C.Y is the program text of the containing program.
  • Le domaine d’accessibilité de A.Z est le texte de programme de A.The accessibility domain of A.Z is the program text of A.
  • Le domaine d’accessibilité de B.Z et B.D est le texte de programme de B, y compris le texte de programme de B.C et B.D.The accessibility domain of B.Z and B.D is the program text of B, including the program text of B.C and B.D.
  • Le domaine d’accessibilité de B.C.Z est le texte de programme de B.C.The accessibility domain of B.C.Z is the program text of B.C.
  • Le domaine d’accessibilité de B.D.X et B.D.Y est le texte de programme de B, y compris le texte de programme de B.C et B.D.The accessibility domain of B.D.X and B.D.Y is the program text of B, including the program text of B.C and B.D.
  • Le domaine d’accessibilité de B.D.Z est le texte de programme de B.D.The accessibility domain of B.D.Z is the program text of B.D.

Comme l’illustre l’exemple, le domaine d’accessibilité d’un membre n’est jamais plus grand que celui d’un type conteneur.As the example illustrates, the accessibility domain of a member is never larger than that of a containing type. Par exemple, même si tous les membres X ont une accessibilité déclarée publique, tous les A.X mais ont des domaines d’accessibilité qui sont limités par un type conteneur.For example, even though all X members have public declared accessibility, all but A.X have accessibility domains that are constrained by a containing type.

Comme décrit dans membres, tous les membres d’une classe de base, à l’exception des constructeurs d’instance, des destructeurs et des constructeurs statiques, sont hérités par les types dérivés.As described in Members, all members of a base class, except for instance constructors, destructors and static constructors, are inherited by derived types. Cela comprend même les membres privés d’une classe de base.This includes even private members of a base class. Toutefois, le domaine d’accessibilité d’un membre privé comprend uniquement le texte de programme du type dans lequel le membre est déclaré.However, the accessibility domain of a private member includes only the program text of the type in which the member is declared. Dans l’exempleIn the example

class A
{
    int x;

    static void F(B b) {
        b.x = 1;        // Ok
    }
}

class B: A
{
    static void F(B b) {
        b.x = 1;        // Error, x not accessible
    }
}

la classe B hérite du x de membre privé de la classe A.the B class inherits the private member x from the A class. Étant donné que le membre est privé, il est uniquement accessible dans le class_body de A.Because the member is private, it is only accessible within the class_body of A. Ainsi, l’accès à b.x réussit dans la méthode A.F, mais échoue dans la méthode B.F.Thus, the access to b.x succeeds in the A.F method, but fails in the B.F method.

Accès protégé pour les membres d’instanceProtected access for instance members

Lorsqu’un membre d’instance protected est accessible en dehors du texte de programme de la classe dans laquelle il est déclaré, et quand un membre d’instance protected internal est accessible en dehors du texte de programme du programme dans lequel il est déclaré, l’accès doit avoir lieu dans une déclaration de classe qui dérive de la classe dans laquelle il est déclaré.When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. En outre, l’accès doit être effectué par le biais d’une instance de ce type de classe dérivée ou d’un type de classe construit à partir de celui-ci.Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. Cette restriction empêche une classe dérivée d’accéder aux membres protégés d’autres classes dérivées, même lorsque les membres sont hérités de la même classe de base.This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.

Laissez B être une classe de base qui déclare un membre d’instance protégé Met laissez D être une classe qui dérive de B.Let B be a base class that declares a protected instance member M, and let D be a class that derives from B. Dans le class_body de D, l’accès aux M peut prendre l’une des formes suivantes :Within the class_body of D, access to M can take one of the following forms:

  • Type_name ou primary_expression non qualifié de la Mde formulaire.An unqualified type_name or primary_expression of the form M.
  • Primary_expression de la forme E.M, à condition que le type de E soit T ou une classe dérivée de T, où T est le type de classe D, ou un type de classe construit à partir de DA primary_expression of the form E.M, provided the type of E is T or a class derived from T, where T is the class type D, or a class type constructed from D
  • Primary_expression de la base.Mde formulaire.A primary_expression of the form base.M.

En plus de ces formes d’accès, une classe dérivée peut accéder à un constructeur d’instance protégé d’une classe de base dans un constructor_initializer (initialiseurs de constructeur).In addition to these forms of access, a derived class can access a protected instance constructor of a base class in a constructor_initializer (Constructor initializers).

Dans l’exempleIn the example

public class A
{
    protected int x;

    static void F(A a, B b) {
        a.x = 1;        // Ok
        b.x = 1;        // Ok
    }
}

public class B: A
{
    static void F(A a, B b) {
        a.x = 1;        // Error, must access through instance of B
        b.x = 1;        // Ok
    }
}

dans A, il est possible d’accéder à des x par le biais d’instances de A et B, car dans les deux cas, l’accès s’effectue par le biais d’une instance de A ou d’une classe dérivée de A.within A, it is possible to access x through instances of both A and B, since in either case the access takes place through an instance of A or a class derived from A. Toutefois, dans B, il n’est pas possible d’accéder à x par le biais d’une instance de A, car A ne dérive pas de B.However, within B, it is not possible to access x through an instance of A, since A does not derive from B.

Dans l’exempleIn the example

class C<T>
{
    protected T x;
}

class D<T>: C<T>
{
    static void F() {
        D<T> dt = new D<T>();
        D<int> di = new D<int>();
        D<string> ds = new D<string>();
        dt.x = default(T);
        di.x = 123;
        ds.x = "test";
    }
}

les trois assignations à x sont autorisées, car elles ont toutes lieu via des instances de types de classe construits à partir du type générique.the three assignments to x are permitted because they all take place through instances of class types constructed from the generic type.

Contraintes d’accessibilitéAccessibility constraints

Plusieurs constructions dans le C# langage requièrent qu’un type soit au moins aussi accessible qu' un membre ou un autre type.Several constructs in the C# language require a type to be at least as accessible as a member or another type. Un T de type est dit être au moins aussi accessible qu’un membre ou un type M si le domaine d’accessibilité de T est un sur-ensemble du domaine d’accessibilité de M.A type T is said to be at least as accessible as a member or type M if the accessibility domain of T is a superset of the accessibility domain of M. En d’autres termes, T est au moins aussi accessible que M si T est accessible dans tous les contextes dans lesquels M est accessible.In other words, T is at least as accessible as M if T is accessible in all contexts in which M is accessible.

Les contraintes d’accessibilité suivantes existent :The following accessibility constraints exist:

  • La classe de base directe d’un type de classe doit être au moins aussi accessible que le type de classe lui-même.The direct base class of a class type must be at least as accessible as the class type itself.
  • Les interfaces de base explicites d’un type d’interface doivent être au moins aussi accessibles que le type d’interface lui-même.The explicit base interfaces of an interface type must be at least as accessible as the interface type itself.
  • Le type de retour et les types de paramètres d’un type délégué doivent être au moins aussi accessibles que le type délégué lui-même.The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself.
  • Le type d’une constante doit être au moins aussi accessible que la constante elle-même.The type of a constant must be at least as accessible as the constant itself.
  • Le type d’un champ doit être au moins aussi accessible que le champ lui-même.The type of a field must be at least as accessible as the field itself.
  • Le type de retour et les types de paramètres d’une méthode doivent être au moins aussi accessibles que la méthode elle-même.The return type and parameter types of a method must be at least as accessible as the method itself.
  • Le type d’une propriété doit être au moins aussi accessible que la propriété elle-même.The type of a property must be at least as accessible as the property itself.
  • Le type d’un événement doit être au moins aussi accessible que l’événement lui-même.The type of an event must be at least as accessible as the event itself.
  • Le type et les types de paramètres d’un indexeur doivent être au moins aussi accessibles que l’indexeur lui-même.The type and parameter types of an indexer must be at least as accessible as the indexer itself.
  • Le type de retour et les types de paramètres d’un opérateur doivent être au moins aussi accessibles que l’opérateur lui-même.The return type and parameter types of an operator must be at least as accessible as the operator itself.
  • Les types de paramètres d’un constructeur d’instance doivent être au moins aussi accessibles que le constructeur d’instance lui-même.The parameter types of an instance constructor must be at least as accessible as the instance constructor itself.

Dans l’exempleIn the example

class A {...}

public class B: A {...}

la classe B génère une erreur au moment de la compilation, car A n’est pas au moins aussi accessible que B.the B class results in a compile-time error because A is not at least as accessible as B.

De même, dans l’exempleLikewise, in the example

class A {...}

public class B
{
    A F() {...}

    internal A G() {...}

    public A H() {...}
}

la méthode H dans B entraîne une erreur de compilation, car le type de retour A n’est pas au moins aussi accessible que la méthode.the H method in B results in a compile-time error because the return type A is not at least as accessible as the method.

Signatures et surchargeSignatures and overloading

Les méthodes, constructeurs d’instance, indexeurs et opérateurs sont caractérisés par leurs signatures:Methods, instance constructors, indexers, and operators are characterized by their signatures:

  • La signature d’une méthode se compose du nom de la méthode, du nombre de paramètres de type et du type et du type (valeur, référence ou sortie) de chacun de ses paramètres formels, pris en compte dans l’ordre de gauche à droite.The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. Pour ces raisons, tout paramètre de type de la méthode qui se produit dans le type d’un paramètre formel est identifié par son nom, mais par sa position ordinale dans la liste d’arguments de type de la méthode.For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. La signature d’une méthode n’inclut pas spécifiquement le type de retour, le modificateur params qui peut être spécifié pour le paramètre le plus à droite, ni les contraintes de paramètre de type facultatives.The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.
  • La signature d’un constructeur d’instance se compose du type et du type (valeur, référence ou sortie) de chacun de ses paramètres formels, pris en compte dans l’ordre de gauche à droite.The signature of an instance constructor consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. La signature d’un constructeur d’instance n’inclut pas spécifiquement le modificateur params qui peut être spécifié pour le paramètre le plus à droite.The signature of an instance constructor specifically does not include the params modifier that may be specified for the right-most parameter.
  • La signature d’un indexeur se compose du type de chacun de ses paramètres formels, pris en compte dans l’ordre de gauche à droite.The signature of an indexer consists of the type of each of its formal parameters, considered in the order left to right. La signature d’un indexeur n’inclut pas spécifiquement le type d’élément et n’inclut pas non plus le modificateur params qui peut être spécifié pour le paramètre le plus à droite.The signature of an indexer specifically does not include the element type, nor does it include the params modifier that may be specified for the right-most parameter.
  • La signature d’un opérateur se compose du nom de l’opérateur et du type de chacun de ses paramètres formels, pris en compte dans l’ordre de gauche à droite.The signature of an operator consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. La signature d’un opérateur n’inclut pas spécifiquement le type de résultat.The signature of an operator specifically does not include the result type.

Les signatures sont le mécanisme d’activation pour la surcharge des membres dans des classes, des structures et des interfaces :Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces:

  • La surcharge de méthodes permet à une classe, un struct ou une interface de déclarer plusieurs méthodes portant le même nom, à condition que leurs signatures soient uniques dans cette classe, structure ou interface.Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
  • La surcharge des constructeurs d’instance permet à une classe ou un struct de déclarer plusieurs constructeurs d’instance, à condition que leurs signatures soient uniques au sein de cette classe ou de ce struct.Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct.
  • La surcharge d’indexeurs permet à une classe, un struct ou une interface de déclarer plusieurs indexeurs, à condition que leurs signatures soient uniques au sein de cette classe, structure ou interface.Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface.
  • La surcharge des opérateurs permet à une classe ou un struct de déclarer plusieurs opérateurs portant le même nom, à condition que leurs signatures soient uniques au sein de cette classe ou de ce struct.Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct.

Bien que les modificateurs de paramètres out et ref soient considérés comme faisant partie d’une signature, les membres déclarés dans un même type ne peuvent pas être différents dans la signature uniquement par ref et out.Although out and ref parameter modifiers are considered part of a signature, members declared in a single type cannot differ in signature solely by ref and out. Une erreur de compilation se produit si deux membres sont déclarés dans le même type avec des signatures qui seraient les mêmes si tous les paramètres dans les deux méthodes avec des modificateurs out ont été modifiés en ref modificateurs.A compile-time error occurs if two members are declared in the same type with signatures that would be the same if all parameters in both methods with out modifiers were changed to ref modifiers. À d’autres fins de correspondance de signature (par exemple, le masquage ou la substitution), ref et out sont considérés comme faisant partie de la signature et ne correspondent pas mutuellement.For other purposes of signature matching (e.g., hiding or overriding), ref and out are considered part of the signature and do not match each other. (Cette restriction consiste à permettre C# aux programmes d’être facilement traduits pour s’exécuter sur le Common Language Infrastructure (interface de commande), ce qui ne permet pas de définir des méthodes qui diffèrent uniquement dans ref et out.)(This restriction is to allow C#  programs to be easily translated to run on the Common Language Infrastructure (CLI), which does not provide a way to define methods that differ solely in ref and out.)

Pour les besoins des signatures, les types object et dynamic sont considérés comme identiques.For the purposes of signatures, the types object and dynamic are considered the same. Les membres déclarés dans un même type ne peuvent donc pas être différents dans la signature uniquement par object et dynamic.Members declared in a single type can therefore not differ in signature solely by object and dynamic.

L’exemple suivant montre un ensemble de déclarations de méthode surchargées, ainsi que leurs signatures.The following example shows a set of overloaded method declarations along with their signatures.

interface ITest
{
    void F();                        // F()

    void F(int x);                   // F(int)

    void F(ref int x);               // F(ref int)

    void F(out int x);               // F(out int)      error

    void F(int x, int y);            // F(int, int)

    int F(string s);                 // F(string)

    int F(int x);                    // F(int)          error

    void F(string[] a);              // F(string[])

    void F(params string[] a);       // F(string[])     error
}

Notez que les modificateurs de paramètre ref et out (paramètres de méthode) font partie d’une signature.Note that any ref and out parameter modifiers (Method parameters) are part of a signature. Ainsi, les F(int) et les F(ref int) sont des signatures uniques.Thus, F(int) and F(ref int) are unique signatures. Toutefois, F(ref int) et F(out int) ne peuvent pas être déclarés dans la même interface, car leurs signatures diffèrent uniquement par ref et out.However, F(ref int) and F(out int) cannot be declared within the same interface because their signatures differ solely by ref and out. Notez également que le type de retour et le modificateur de params ne font pas partie d’une signature. il n’est donc pas possible de se surcharger uniquement en fonction du type de retour ou de l’inclusion ou de l’exclusion du modificateur params.Also, note that the return type and the params modifier are not part of a signature, so it is not possible to overload solely based on return type or on the inclusion or exclusion of the params modifier. Ainsi, les déclarations des méthodes F(int) et F(params string[]) identifiées ci-dessus entraînent une erreur de compilation.As such, the declarations of the methods F(int) and F(params string[]) identified above result in a compile-time error.

PortéesScopes

La portée d’un nom est la région du texte de programme dans laquelle il est possible de faire référence à l’entité déclarée par le nom sans qualification du nom.The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Les portées peuvent être imbriquéeset une portée interne peut redéclarer la signification d’un nom à partir d’une étendue externe (Toutefois, cela ne supprime pas la restriction imposée par les déclarations dans un bloc imbriqué, il n’est pas possible de déclarer une variable locale portant le même nom qu’une variable locale dans un bloc englobant).Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by Declarations that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block). Le nom de l’étendue externe est ensuite dit masqué dans la région du texte de programme couvert par l’étendue interne, et l’accès au nom externe n’est possible qu’en qualifiant le nom.The name from the outer scope is then said to be hidden in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name.

  • La portée d’un membre d’espace de noms déclaré par un namespace_member_declaration (membres d’espace de noms) sans namespace_declaration englobante correspond au texte de programme entier.The scope of a namespace member declared by a namespace_member_declaration (Namespace members) with no enclosing namespace_declaration is the entire program text.
  • La portée d’un membre d’espace de noms déclaré par un namespace_member_declaration dans un namespace_declaration dont le nom qualifié complet est N est la namespace_body de chaque namespace_declaration dont le nom qualifié complet est N ou commence par N, suivi d’un point.The scope of a namespace member declared by a namespace_member_declaration within a namespace_declaration whose fully qualified name is N is the namespace_body of every namespace_declaration whose fully qualified name is N or starts with N, followed by a period.
  • L’étendue de nom définie par un extern_alias_directive s’étend sur le using_directives, global_attributes et namespace_member_declarations de son corps d’unité de compilation ou d’espace de noms contenant immédiatement.The scope of name defined by an extern_alias_directive extends over the using_directives, global_attributes and namespace_member_declarations of its immediately containing compilation unit or namespace body. Un extern_alias_directive ne contribue pas à la création de nouveaux membres dans l’espace de déclaration sous-jacent.An extern_alias_directive does not contribute any new members to the underlying declaration space. En d’autres termes, un extern_alias_directive n’est pas transitif, mais affecte uniquement l’unité de compilation ou le corps de l’espace de noms dans lequel il se produit.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.
  • L’étendue d’un nom défini ou importé par un using_directive (à l’aide de directives) s’étend sur le namespace_member_declarations du compilation_unit ou namespace_body dans lequel la using_directive se produit.The scope of a name defined or imported by a using_directive (Using directives) extends over the namespace_member_declarations of the compilation_unit or namespace_body in which the using_directive occurs. Une using_directive peut rendre zéro ou plusieurs noms d’espaces de noms, de types ou de membres disponibles dans une compilation_unit ou namespace_bodyparticulière, mais ne contribue pas à de nouveaux membres dans l’espace de déclaration sous-jacent.A using_directive may make zero or more namespace, type or member names available within a particular compilation_unit or namespace_body, but does not contribute any new members to the underlying declaration space. En d’autres termes, un using_directive n’est pas transitif, mais affecte uniquement le compilation_unit ou namespace_body dans lequel il se produit.In other words, a using_directive is not transitive but rather affects only the compilation_unit or namespace_body in which it occurs.
  • La portée d’un paramètre de type déclaré par un type_parameter_list sur un class_declaration (déclarations de classe) est la class_base, type_parameter_constraints_clauses et class_body de cette class_declaration.The scope of a type parameter declared by a type_parameter_list on a class_declaration (Class declarations) is the class_base, type_parameter_constraints_clauses, and class_body of that class_declaration.
  • La portée d’un paramètre de type déclaré par un type_parameter_list sur un struct_declaration (déclarations de struct) est la struct_interfaces, type_parameter_constraints_clauses et struct_body de cette struct_declaration.The scope of a type parameter declared by a type_parameter_list on a struct_declaration (Struct declarations) is the struct_interfaces, type_parameter_constraints_clauses, and struct_body of that struct_declaration.
  • La portée d’un paramètre de type déclaré par un type_parameter_list sur une interface_declaration (déclarations d’interface) est le interface_base, type_parameter_constraints_clauses et interface_body de cette interface_declaration.The scope of a type parameter declared by a type_parameter_list on an interface_declaration (Interface declarations) is the interface_base, type_parameter_constraints_clauses, and interface_body of that interface_declaration.
  • La portée d’un paramètre de type déclaré par un type_parameter_list sur un delegate_declaration (déclarations de délégué) est le return_type, le formal_parameter_listet type_parameter_constraints_clauses de ce delegate_declaration.The scope of a type parameter declared by a type_parameter_list on a delegate_declaration (Delegate declarations) is the return_type, formal_parameter_list, and type_parameter_constraints_clauses of that delegate_declaration.
  • La portée d’un membre déclaré par un class_member_declaration (corps de classe) est le class_body dans lequel la déclaration se produit.The scope of a member declared by a class_member_declaration (Class body) is the class_body in which the declaration occurs. En outre, l’étendue d’un membre de classe s’étend au class_body de ces classes dérivées qui sont incluses dans le domaine d’accessibilité (domaines d’accessibilité) du membre.In addition, the scope of a class member extends to the class_body of those derived classes that are included in the accessibility domain (Accessibility domains) of the member.
  • La portée d’un membre déclaré par un struct_member_declaration (membres struct) est le struct_body dans lequel la déclaration se produit.The scope of a member declared by a struct_member_declaration (Struct members) is the struct_body in which the declaration occurs.
  • La portée d’un membre déclaré par un enum_member_declaration (membres enum) est le enum_body dans lequel la déclaration se produit.The scope of a member declared by an enum_member_declaration (Enum members) is the enum_body in which the declaration occurs.
  • La portée d’un paramètre déclaré dans une method_declaration (méthodes) est le method_body de ce method_declaration.The scope of a parameter declared in a method_declaration (Methods) is the method_body of that method_declaration.
  • La portée d’un paramètre déclaré dans un indexer_declaration (indexeurs) est le accessor_declarations de ce indexer_declaration.The scope of a parameter declared in an indexer_declaration (Indexers) is the accessor_declarations of that indexer_declaration.
  • La portée d’un paramètre déclaré dans un operator_declaration (opérateurs) est le bloc de ce operator_declaration.The scope of a parameter declared in an operator_declaration (Operators) is the block of that operator_declaration.
  • La portée d’un paramètre déclaré dans une constructor_declaration (constructeurs d’instance) est le constructor_initializer et le bloc de ce constructor_declaration.The scope of a parameter declared in a constructor_declaration (Instance constructors) is the constructor_initializer and block of that constructor_declaration.
  • La portée d’un paramètre déclaré dans une lambda_expression (expressions de fonction anonymes) est la anonymous_function_body de ce lambda_expressionThe scope of a parameter declared in a lambda_expression (Anonymous function expressions) is the anonymous_function_body of that lambda_expression
  • La portée d’un paramètre déclaré dans une anonymous_method_expression (expressions de fonction anonymes) est le bloc de ce anonymous_method_expression.The scope of a parameter declared in an anonymous_method_expression (Anonymous function expressions) is the block of that anonymous_method_expression.
  • La portée d’une étiquette déclarée dans une labeled_statement (instructions étiquetées) est le bloc dans lequel la déclaration se produit.The scope of a label declared in a labeled_statement (Labeled statements) is the block in which the declaration occurs.
  • La portée d’une variable locale déclarée dans une local_variable_declaration (déclarations de variables locales) est le bloc dans lequel la déclaration se produit.The scope of a local variable declared in a local_variable_declaration (Local variable declarations) is the block in which the declaration occurs.
  • La portée d’une variable locale déclarée dans une switch_block d’une instruction switch (l’instruction switch) est la switch_block.The scope of a local variable declared in a switch_block of a switch statement (The switch statement) is the switch_block.
  • La portée d’une variable locale déclarée dans une for_initializer d’une instruction for (l’instruction for) est la for_initializer, la for_condition, la for_iteratoret l' instruction contenue de l’instruction for.The scope of a local variable declared in a for_initializer of a for statement (The for statement) is the for_initializer, the for_condition, the for_iterator, and the contained statement of the for statement.
  • La portée d’une constante locale déclarée dans une local_constant_declaration (déclarations de constantes locales) est le bloc dans lequel la déclaration se produit.The scope of a local constant declared in a local_constant_declaration (Local constant declarations) is the block in which the declaration occurs. Il s’agit d’une erreur au moment de la compilation pour faire référence à une constante locale dans une position textuelle qui précède son constant_declarator.It is a compile-time error to refer to a local constant in a textual position that precedes its constant_declarator.
  • La portée d’une variable déclarée dans le cadre d’un foreach_statement, using_statement lock_statement ou query_expression est déterminée par le développement de la construction donnée.The scope of a variable declared as part of a foreach_statement, using_statement, lock_statement or query_expression is determined by the expansion of the given construct.

Dans l’étendue d’un espace de noms, d’une classe, d’une structure ou d’un membre d’énumération, il est possible de faire référence au membre dans une position textuelle qui précède la déclaration du membre.Within the scope of a namespace, class, struct, or enumeration member it is possible to refer to the member in a textual position that precedes the declaration of the member. Exemple :For example

class A
{
    void F() {
        i = 1;
    }

    int i = 0;
}

Ici, il est valide pour F faire référence à i avant qu’il ne soit déclaré.Here, it is valid for F to refer to i before it is declared.

Dans l’étendue d’une variable locale, il s’agit d’une erreur de compilation qui fait référence à la variable locale dans une position textuelle qui précède la local_variable_declarator de la variable locale.Within the scope of a local variable, it is a compile-time error to refer to the local variable in a textual position that precedes the local_variable_declarator of the local variable. Exemple :For example

class A
{
    int i = 0;

    void F() {
        i = 1;                  // Error, use precedes declaration
        int i;
        i = 2;
    }

    void G() {
        int j = (j = 1);        // Valid
    }

    void H() {
        int a = 1, b = ++a;    // Valid
    }
}

Dans la méthode F ci-dessus, la première assignation à i ne fait pas spécifiquement référence au champ déclaré dans l’étendue externe.In the F method above, the first assignment to i specifically does not refer to the field declared in the outer scope. Au lieu de cela, il fait référence à la variable locale et génère une erreur de compilation, car il précède la déclaration de la variable dans le texte.Rather, it refers to the local variable and it results in a compile-time error because it textually precedes the declaration of the variable. Dans la méthode G, l’utilisation de j dans l’initialiseur pour la déclaration de j est valide, car l’utilisation ne précède pas le local_variable_declarator.In the G method, the use of j in the initializer for the declaration of j is valid because the use does not precede the local_variable_declarator. Dans la méthode H, un local_variable_declarator suivant fait correctement référence à une variable locale déclarée dans une local_variable_declarator antérieure au sein du même local_variable_declaration.In the H method, a subsequent local_variable_declarator correctly refers to a local variable declared in an earlier local_variable_declarator within the same local_variable_declaration.

Les règles de portée pour les variables locales sont conçues pour garantir que la signification d’un nom utilisé dans un contexte d’expression est toujours la même dans un bloc.The scoping rules for local variables are designed to guarantee that the meaning of a name used in an expression context is always the same within a block. Si la portée d’une variable locale ne doit s’étendre qu’à partir de sa déclaration à la fin du bloc, alors, dans l’exemple ci-dessus, la première assignation est assignée à la variable d’instance et la deuxième assignation est assignée à la variable locale, ce qui peut aboutir à erreurs au moment de la compilation si les instructions du bloc ont été réorganisées par la suite.If the scope of a local variable were to extend only from its declaration to the end of the block, then in the example above, the first assignment would assign to the instance variable and the second assignment would assign to the local variable, possibly leading to compile-time errors if the statements of the block were later to be rearranged.

La signification d’un nom dans un bloc peut varier selon le contexte dans lequel le nom est utilisé.The meaning of a name within a block may differ based on the context in which the name is used. Dans l’exempleIn the example

using System;

class A {}

class Test
{
    static void Main() {
        string A = "hello, world";
        string s = A;                            // expression context

        Type t = typeof(A);                      // type context

        Console.WriteLine(s);                    // writes "hello, world"
        Console.WriteLine(t);                    // writes "A"
    }
}

le nom A est utilisé dans un contexte d’expression pour faire référence à la variable locale A et dans un contexte de type pour faire référence à la classe A.the name A is used in an expression context to refer to the local variable A and in a type context to refer to the class A.

Masquage de nomName hiding

La portée d’une entité comprend généralement plus de texte de programme que l’espace de déclaration de l’entité.The scope of an entity typically encompasses more program text than the declaration space of the entity. En particulier, l’étendue d’une entité peut inclure des déclarations qui introduisent de nouveaux espaces de déclaration contenant des entités du même nom.In particular, the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. De telles déclarations entraînent le masquagede l’entité d’origine.Such declarations cause the original entity to become hidden. À l’inverse, une entité est dite visible lorsqu’elle n’est pas masquée.Conversely, an entity is said to be visible when it is not hidden.

Le masquage de nom se produit lorsque les étendues se chevauchent lors de l’imbrication et lorsque les étendues chevauchent l’héritage.Name hiding occurs when scopes overlap through nesting and when scopes overlap through inheritance. Les caractéristiques des deux types de masquage sont décrites dans les sections suivantes.The characteristics of the two types of hiding are described in the following sections.

Masquer par imbricationHiding through nesting

Le masquage de nom via l’imbrication peut se produire en raison de l’imbrication d’espaces de noms ou de types dans les espaces de noms, en raison de l’imbrication de types dans des classes ou des structs, et de la suite de déclarations de variables locales et de paramètres.Name hiding through nesting can occur as a result of nesting namespaces or types within namespaces, as a result of nesting types within classes or structs, and as a result of parameter and local variable declarations.

Dans l’exempleIn the example

class A
{
    int i = 0;

    void F() {
        int i = 1;
    }

    void G() {
        i = 1;
    }
}

dans la méthode F, la variable d’instance i est masquée par la variable locale i, mais dans la méthode G, i fait toujours référence à la variable d’instance.within the F method, the instance variable i is hidden by the local variable i, but within the G method, i still refers to the instance variable.

Lorsqu’un nom dans une portée interne masque un nom dans une portée externe, il masque toutes les occurrences surchargées de ce nom.When a name in an inner scope hides a name in an outer scope, it hides all overloaded occurrences of that name. Dans l’exempleIn the example

class Outer
{
    static void F(int i) {}

    static void F(string s) {}

    class Inner
    {
        void G() {
            F(1);              // Invokes Outer.Inner.F
            F("Hello");        // Error
        }

        static void F(long l) {}
    }
}

l’appel F(1) appelle le F déclaré dans Inner, car toutes les occurrences externes de F sont masquées par la déclaration interne.the call F(1) invokes the F declared in Inner because all outer occurrences of F are hidden by the inner declaration. Pour la même raison, l’appel F("Hello") génère une erreur au moment de la compilation.For the same reason, the call F("Hello") results in a compile-time error.

Masquer par héritageHiding through inheritance

Le masquage de nom par héritage se produit lorsque des classes ou des structs déclarent des noms qui ont été hérités de classes de base.Name hiding through inheritance occurs when classes or structs redeclare names that were inherited from base classes. Ce type de masquage de nom prend l’une des formes suivantes :This type of name hiding takes one of the following forms:

  • Une constante, un champ, une propriété, un événement ou un type introduit dans une classe ou un struct masque tous les membres de la classe de base portant le même nom.A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.
  • Une méthode introduite dans une classe ou un struct masque tous les membres de classe de base non-méthode portant le même nom, ainsi que toutes les méthodes de la classe de base ayant la même signature (nom de méthode et nombre de paramètres, modificateurs et types).A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types).
  • Un indexeur introduit dans une classe ou un struct masque tous les indexeurs de la classe de base avec la même signature (nombre de paramètres et types).An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types).

Les règles gouvernant les déclarations d’opérateur (opérateurs) rendent impossible une classe dérivée de déclarer un opérateur avec la même signature qu’un opérateur dans une classe de base.The rules governing operator declarations (Operators) make it impossible for a derived class to declare an operator with the same signature as an operator in a base class. Ainsi, les opérateurs ne sont jamais masqués.Thus, operators never hide one another.

Contrairement au masquage d’un nom dans une portée externe, le masquage d’un nom accessible à partir d’une portée héritée entraîne le signalement d’un avertissement.Contrary to hiding a name from an outer scope, hiding an accessible name from an inherited scope causes a warning to be reported. Dans l’exempleIn the example

class Base
{
    public void F() {}
}

class Derived: Base
{
    public void F() {}        // Warning, hiding an inherited name
}

la déclaration de F dans Derived entraîne le signalement d’un avertissement.the declaration of F in Derived causes a warning to be reported. Le masquage d’un nom hérité n’est pas une erreur, car cela empêche l’évolution distincte des classes de base.Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. Par exemple, la situation ci-dessus peut être due au fait qu’une version ultérieure de Base introduit une méthode F qui n’était pas présente dans une version antérieure de la classe.For example, the above situation might have come about because a later version of Base introduced an F method that wasn't present in an earlier version of the class. Si la situation précédente était une erreur, toute modification apportée à une classe de base dans une bibliothèque de classes avec version distincte pourrait entraîner la non-validité des classes dérivées.Had the above situation been an error, then any change made to a base class in a separately versioned class library could potentially cause derived classes to become invalid.

L’avertissement provoqué par le masquage d’un nom hérité peut être éliminé grâce à l’utilisation du modificateur new :The warning caused by hiding an inherited name can be eliminated through use of the new modifier:

class Base
{
    public void F() {}
}

class Derived: Base
{
    new public void F() {}
}

Le modificateur de new indique que le F dans Derived est « New », et qu’il est effectivement destiné à masquer le membre hérité.The new modifier indicates that the F in Derived is "new", and that it is indeed intended to hide the inherited member.

Une déclaration d’un nouveau membre masque un membre hérité uniquement dans la portée du nouveau membre.A declaration of a new member hides an inherited member only within the scope of the new member.

class Base
{
    public static void F() {}
}

class Derived: Base
{
    new private static void F() {}    // Hides Base.F in Derived only
}

class MoreDerived: Derived
{
    static void G() { F(); }          // Invokes Base.F
}

Dans l’exemple ci-dessus, la déclaration de F dans Derived masque la F qui a été héritée de Base, mais étant donné que la nouvelle F de Derived a un accès privé, son étendue ne s’étend pas à MoreDerived.In the example above, the declaration of F in Derived hides the F that was inherited from Base, but since the new F in Derived has private access, its scope does not extend to MoreDerived. Ainsi, l’appel F() dans MoreDerived.G est valide et appellera Base.F.Thus, the call F() in MoreDerived.G is valid and will invoke Base.F.

Noms d’espaces de noms et de typesNamespace and type names

Plusieurs contextes dans un C# programme nécessitent la spécification d’une namespace_name ou d’un type_name .Several contexts in a C# program require a namespace_name or a type_name to be specified.

namespace_name
    : namespace_or_type_name
    ;

type_name
    : namespace_or_type_name
    ;

namespace_or_type_name
    : identifier type_argument_list?
    | namespace_or_type_name '.' identifier type_argument_list?
    | qualified_alias_member
    ;

Un namespace_name est un namespace_or_type_name qui fait référence à un espace de noms.A namespace_name is a namespace_or_type_name that refers to a namespace. Après la résolution comme décrit ci-dessous, la namespace_or_type_name d’un namespace_name doit faire référence à un espace de noms ou une erreur de compilation se produit.Following resolution as described below, the namespace_or_type_name of a namespace_name must refer to a namespace, or otherwise a compile-time error occurs. Aucun argument de type (arguments de type) ne peut être présent dans une namespace_name (seuls les types peuvent avoir des arguments de type).No type arguments (Type arguments) can be present in a namespace_name (only types can have type arguments).

Un type_name est un namespace_or_type_name qui fait référence à un type.A type_name is a namespace_or_type_name that refers to a type. Après la résolution comme décrit ci-dessous, la namespace_or_type_name d’un type_name doit faire référence à un type, ou une erreur de compilation se produit.Following resolution as described below, the namespace_or_type_name of a type_name must refer to a type, or otherwise a compile-time error occurs.

Si le namespace_or_type_name est un membre d’alias qualifié, son sens est décrit dans qualificateurs d’alias d’espace de noms.If the namespace_or_type_name is a qualified-alias-member its meaning is as described in Namespace alias qualifiers. Dans le cas contraire, un namespace_or_type_name a l’une des quatre formes suivantes :Otherwise, a namespace_or_type_name has one of four forms:

  • I
  • I<A1, ..., Ak>
  • N.I
  • N.I<A1, ..., Ak>

I est un identificateur unique, N est un namespace_or_type_name et <A1, ..., Ak> est un type_argument_listfacultatif.where I is a single identifier, N is a namespace_or_type_name and <A1, ..., Ak> is an optional type_argument_list. Si aucun type_argument_list n’est spécifié, envisagez k à zéro.When no type_argument_list is specified, consider k to be zero.

La signification d’un namespace_or_type_name est déterminée comme suit :The meaning of a namespace_or_type_name is determined as follows:

  • Si le namespace_or_type_name se présente sous la forme I ou sous la forme I<A1, ..., Ak>:If the namespace_or_type_name is of the form I or of the form I<A1, ..., Ak>:
    • Si K est égal à zéro et que le namespace_or_type_name apparaît dans une déclaration de méthode générique (méthodes) et si cette déclaration comprend un paramètre de type (paramètres de type) avec le nom I, le namespace_or_type_name fait référence à ce paramètre de type.If K is zero and the namespace_or_type_name appears within a generic method declaration (Methods) and if that declaration includes a type parameter (Type parameters) with name I, then the namespace_or_type_name refers to that type parameter.
    • Sinon, si le namespace_or_type_name apparaît dans une déclaration de type, pour chaque type d’instance T (le type d’instance), en commençant par le type d’instance de cette déclaration de type et en poursuivant avec le type d’instance de chaque déclaration de classe ou de struct englobante (le cas échéant) :Otherwise, if the namespace_or_type_name appears within a type declaration, then for each instance type T (The instance type), starting with the instance type of that type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):
      • Si K est égal à zéro et que la déclaration de T comprend un paramètre de type avec le nom I, le namespace_or_type_name fait référence à ce paramètre de type.If K is zero and the declaration of T includes a type parameter with name I, then the namespace_or_type_name refers to that type parameter.
      • Sinon, si le namespace_or_type_name apparaît dans le corps de la déclaration de type et que T ou l’un de ses types de base contient un type accessible imbriqué ayant le nom I et Kparamètres de type  , le namespace_or_type_name fait référence à ce type construit avec les arguments de type donnés.Otherwise, if the namespace_or_type_name appears within the body of the type declaration, and T or any of its base types contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. S’il existe plusieurs types de ce type, le type déclaré dans le type plus dérivé est sélectionné.If there is more than one such type, the type declared within the more derived type is selected. Notez que les membres qui ne sont pas de type (constantes, champs, méthodes, propriétés, indexeurs, opérateurs, constructeurs d’instance, destructeurs et constructeurs statiques) et les membres de type avec un nombre différent de paramètres de type sont ignorés lors de la détermination de la signification de la namespace_or_type_name.Note that non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, destructors, and static constructors) and type members with a different number of type parameters are ignored when determining the meaning of the namespace_or_type_name.
    • Si les étapes précédentes n’ont pas réussi, pour chaque espace de noms N, en commençant par l’espace de noms dans lequel le namespace_or_type_name se produit, en continuant avec chaque espace de noms englobant (le cas échéant) et en terminant par l’espace de noms global, les étapes suivantes sont évaluées jusqu’à ce qu’une entité soit localisée :If the previous steps were unsuccessful then, for each namespace N, starting with the namespace in which the namespace_or_type_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
      • Si K est égal à zéro et que I est le nom d’un espace de noms dans N, alors :If K is zero and I is the name of a namespace in N, then:
        • Si l’emplacement où le namespace_or_type_name se produit est entouré d’une déclaration d’espace de noms pour N et que la déclaration d’espace de noms contient un extern_alias_directive ou using_alias_directive qui associe le nom I à un espace de noms ou à un type, le namespace_or_type_name est ambigu et une erreur de compilation se produit.If the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • Dans le cas contraire, le namespace_or_type_name fait référence à l’espace de noms nommé I dans N.Otherwise, the namespace_or_type_name refers to the namespace named I in N.
      • Dans le cas contraire, si N contient un type accessible dont le nom I et Kparamètres de type  , alors :Otherwise, if N contains an accessible type having name I and K type parameters, then:
        • Si K est égal à zéro et que l’emplacement où le namespace_or_type_name se produit est entouré d’une déclaration d’espace de noms pour N et que la déclaration d’espace de noms contient une extern_alias_directive ou une using_alias_directive qui associe le nom I à un espace de noms ou à un type, le namespace_or_type_name est ambigu et une erreur de compilation se produit.If K is zero and the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • Sinon, le namespace_or_type_name fait référence au type construit avec les arguments de type donnés.Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
      • Sinon, si l’emplacement où le namespace_or_type_name se produit est entouré d’une déclaration d’espace de noms pour N:Otherwise, if the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N:
        • Si K est égal à zéro et que la déclaration d’espace de noms contient une extern_alias_directive ou using_alias_directive qui associe le nom I à un espace de noms ou un type importé, le namespace_or_type_name fait référence à cet espace de noms ou type.If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the namespace_or_type_name refers to that namespace or type.
        • Sinon, si les espaces de noms et les déclarations de type importés par les using_namespace_directives et using_alias_directives de la déclaration d’espace de noms contiennent exactement un type accessible avec le nom I et Kparamètres de type  , alors le namespace_or_type_name fait référence à ce type construit avec les arguments de type donnés.Otherwise, if the namespaces and type declarations imported by the using_namespace_directives and using_alias_directives of the namespace declaration contain exactly one accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
        • Sinon, si les espaces de noms et les déclarations de type importés par le using_namespace_directives et using_alias_directives de la déclaration d’espace de noms contiennent plusieurs types accessibles ayant un nom I et Kparamètres de type  , le namespace_or_type_name est ambigu et une erreur se produit.Otherwise, if the namespaces and type declarations imported by the using_namespace_directives and using_alias_directives of the namespace declaration contain more than one accessible type having name I and K type parameters, then the namespace_or_type_name is ambiguous and an error occurs.
    • Dans le cas contraire, la namespace_or_type_name n’est pas définie et une erreur de compilation se produit.Otherwise, the namespace_or_type_name is undefined and a compile-time error occurs.
  • Dans le cas contraire, le namespace_or_type_name se présente sous la forme N.I ou sous la forme N.I<A1, ..., Ak>.Otherwise, the namespace_or_type_name is of the form N.I or of the form N.I<A1, ..., Ak>. N est d’abord résolu en tant que namespace_or_type_name.N is first resolved as a namespace_or_type_name. Si la résolution de N échoue, une erreur de compilation se produit.If the resolution of N is not successful, a compile-time error occurs. Sinon, N.I ou N.I<A1, ..., Ak> est résolu comme suit :Otherwise, N.I or N.I<A1, ..., Ak> is resolved as follows:
    • Si K est égal à zéro et N fait référence à un espace de noms et N contient un espace de noms imbriqué avec le nom I, le namespace_or_type_name fait référence à cet espace de noms imbriqué.If K is zero and N refers to a namespace and N contains a nested namespace with name I, then the namespace_or_type_name refers to that nested namespace.
    • Sinon, si N fait référence à un espace de noms et que N contient un type accessible avec le nom I et Kparamètres de type  , le namespace_or_type_name fait référence à ce type construit avec les arguments de type donnés.Otherwise, if N refers to a namespace and N contains an accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
    • Sinon, si N fait référence à un type de classe ou de struct (éventuellement construit) et N ou que l’une de ses classes de base contient un type accessible imbriqué ayant un nom I et Kparamètres de type  , le namespace_or_type_name fait référence à ce type construit avec les arguments de type donnés.Otherwise, if N refers to a (possibly constructed) class or struct type and N or any of its base classes contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. S’il existe plusieurs types de ce type, le type déclaré dans le type plus dérivé est sélectionné.If there is more than one such type, the type declared within the more derived type is selected. Notez que si la signification de N.I est déterminée dans le cadre de la résolution de la spécification de la classe de base de N, la classe de base directe de N est considérée comme Object (classes de base).Note that if the meaning of N.I is being determined as part of resolving the base class specification of N then the direct base class of N is considered to be object (Base classes).
    • Dans le cas contraire, N.I est un namespace_or_type_namenon valide et une erreur de compilation se produit.Otherwise, N.I is an invalid namespace_or_type_name, and a compile-time error occurs.

Un namespace_or_type_name est autorisé à référencer une classe statique (classes statiques) uniquement siA namespace_or_type_name is permitted to reference a static class (Static classes) only if

  • Le namespace_or_type_name est le T dans un namespace_or_type_name de la forme T.I, ouThe namespace_or_type_name is the T in a namespace_or_type_name of the form T.I, or
  • Le namespace_or_type_name est le T dans un typeof_expression (liste d’arguments1) de la typeof(T)de formulaire.The namespace_or_type_name is the T in a typeof_expression (Argument lists1) of the form typeof(T).

Noms qualifiés completsFully qualified names

Chaque espace de noms et type a un nom qualifié complet, qui identifie de façon unique l’espace de noms ou le type parmi tous les autres.Every namespace and type has a fully qualified name, which uniquely identifies the namespace or type amongst all others. Le nom qualifié complet d’un espace de noms ou d’un type N est déterminé comme suit :The fully qualified name of a namespace or type N is determined as follows:

  • Si N est membre de l’espace de noms global, son nom complet est N.If N is a member of the global namespace, its fully qualified name is N.
  • Dans le cas contraire, son nom complet est S.N, où S est le nom qualifié complet de l’espace de noms ou du type dans lequel N est déclaré.Otherwise, its fully qualified name is S.N, where S is the fully qualified name of the namespace or type in which N is declared.

En d’autres termes, le nom qualifié complet de N est le chemin d’accès hiérarchique complet des identificateurs qui mènent à N, en commençant par l’espace de noms global.In other words, the fully qualified name of N is the complete hierarchical path of identifiers that lead to N, starting from the global namespace. Étant donné que chaque membre d’un espace de noms ou d’un type doit avoir un nom unique, il suit que le nom qualifié complet d’un espace de noms ou d’un type est toujours unique.Because every member of a namespace or type must have a unique name, it follows that the fully qualified name of a namespace or type is always unique.

L’exemple ci-dessous montre plusieurs déclarations d’espace de noms et de type, ainsi que leurs noms complets associés.The example below shows several namespace and type declarations along with their associated fully qualified names.

class A {}                // A

namespace X               // X
{
    class B               // X.B
    {
        class C {}        // X.B.C
    }

    namespace Y           // X.Y
    {
        class D {}        // X.Y.D
    }
}

namespace X.Y             // X.Y
{
    class E {}            // X.Y.E
}

Gestion automatique de la mémoireAutomatic memory management

C#utilise la gestion automatique de la mémoire, qui évite aux développeurs d’allouer et de libérer manuellement la mémoire occupée par les objets.C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Les stratégies de gestion automatique de la mémoire sont implémentées par un garbage collector.Automatic memory management policies are implemented by a garbage collector. Le cycle de vie de la gestion de la mémoire d’un objet est le suivant :The memory management life cycle of an object is as follows:

  1. Lorsque l’objet est créé, la mémoire est allouée, le constructeur est exécuté et l’objet est considéré comme dynamique.When the object is created, memory is allocated for it, the constructor is run, and the object is considered live.
  2. Si l’objet, ou une partie de celui-ci, n’est pas accessible par une continuation d’exécution possible, autre que l’exécution de destructeurs, l’objet est considéré comme n’étant plus utilisé et il est éligible pour la destruction.If the object, or any part of it, cannot be accessed by any possible continuation of execution, other than the running of destructors, the object is considered no longer in use, and it becomes eligible for destruction. Le C# compilateur et le garbage collector peuvent choisir d’analyser le code pour déterminer les références à un objet qui peuvent être utilisées ultérieurement.The C# compiler and the garbage collector may choose to analyze code to determine which references to an object may be used in the future. Par exemple, si une variable locale qui est dans la portée est la seule référence existante à un objet, mais que cette variable locale n’est jamais référencée dans une éventuelle continuation d’exécution à partir du point d’exécution actuel de la procédure, le garbage collector peut (mais n’est pas requis pour) traiter l’objet comme n’étant plus utilisé.For instance, if a local variable that is in scope is the only existing reference to an object, but that local variable is never referred to in any possible continuation of execution from the current execution point in the procedure, the garbage collector may (but is not required to) treat the object as no longer in use.
  3. Une fois que l’objet est éligible pour la destruction, à une date non spécifiée plus tard, ledestructeur (le cas échéant) del’objet est exécuté.Once the object is eligible for destruction, at some unspecified later time the destructor (Destructors) (if any) for the object is run. Dans des circonstances normales, le destructeur de l’objet est exécuté une seule fois, bien que les API spécifiques à l’implémentation puissent autoriser le remplacement de ce comportement.Under normal circumstances the destructor for the object is run once only, though implementation-specific APIs may allow this behavior to be overridden.
  4. Une fois que le destructeur pour un objet est exécuté, si cet objet, ou une partie de celui-ci, n’est pas accessible par toute continuation d’exécution possible, y compris l’exécution de destructeurs, l’objet est considéré comme étant inaccessible et l’objet devient éligible pour la collecte.Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
  5. Enfin, une fois que l’objet est éligible pour la collecte, le garbage collector libère la mémoire associée à cet objet.Finally, at some time after the object becomes eligible for collection, the garbage collector frees the memory associated with that object.

Le garbage collector conserve des informations sur l’utilisation des objets et utilise ces informations pour prendre des décisions de gestion de la mémoire, telles que l’emplacement de la mémoire pour localiser un objet nouvellement créé, quand déplacer un objet, et quand un objet n’est plus utilisé ou n’est pas accessible.The garbage collector maintains information about object usage, and uses this information to make memory management decisions, such as where in memory to locate a newly created object, when to relocate an object, and when an object is no longer in use or inaccessible.

Comme les autres langages qui supposent l’existence d’un C# garbage collector, est conçu de sorte que le garbage collector puisse implémenter une large gamme de stratégies de gestion de la mémoire.Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage collector may implement a wide range of memory management policies. Par exemple, C# ne nécessite pas l’exécution des destructeurs ou la collecte des objets dès qu’ils sont éligibles, ou l’exécution des destructeurs dans un ordre particulier ou sur un thread particulier.For instance, C# does not require that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in any particular order, or on any particular thread.

Le comportement du garbage collector peut être contrôlé, à un certain degré, via des méthodes statiques sur la classe System.GC.The behavior of the garbage collector can be controlled, to some degree, via static methods on the class System.GC. Cette classe peut être utilisée pour demander qu’une collection se produise, que les destructeurs soient exécutés (ou non), et ainsi de suite.This class can be used to request a collection to occur, destructors to be run (or not run), and so forth.

Dans la mesure où le garbage collector est autorisé à atteindre une grande latitude en déterminant quand collecter des objets et exécuter des destructeurs, une implémentation conforme peut produire une sortie qui diffère de celle indiquée par le code suivant.Since the garbage collector is allowed wide latitude in deciding when to collect objects and run destructors, a conforming implementation may produce output that differs from that shown by the following code. Le programmeThe program

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }
}

class B
{
    object Ref;

    public B(object o) {
        Ref = o;
    }

    ~B() {
        Console.WriteLine("Destruct instance of B");
    }
}

class Test
{
    static void Main() {
        B b = new B(new A());
        b = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

crée une instance de la classe A et une instance de la classe B.creates an instance of class A and an instance of class B. Ces objets deviennent éligibles pour garbage collection lorsque la variable b est assignée à la valeur null, car, à ce moment-là, il est impossible pour un code écrit par l’utilisateur d’y accéder.These objects become eligible for garbage collection when the variable b is assigned the value null, since after this time it is impossible for any user-written code to access them. La sortie peut êtreThe output could be either

Destruct instance of A
Destruct instance of B

oror

Destruct instance of B
Destruct instance of A

étant donné que le langage n’impose aucune contrainte sur l’ordre dans lequel les objets sont récupérés par le garbage collector.because the language imposes no constraints on the order in which objects are garbage collected.

Dans les cas subtils, la distinction entre « éligible à la destruction » et « éligible pour la collecte » peut être importante.In subtle cases, the distinction between "eligible for destruction" and "eligible for collection" can be important. Par exemple :For example,

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }

    public void F() {
        Console.WriteLine("A.F");
        Test.RefA = this;
    }
}

class B
{
    public A Ref;

    ~B() {
        Console.WriteLine("Destruct instance of B");
        Ref.F();
    }
}

class Test
{
    public static A RefA;
    public static B RefB;

    static void Main() {
        RefB = new B();
        RefA = new A();
        RefB.Ref = RefA;
        RefB = null;
        RefA = null;

        // A and B now eligible for destruction
        GC.Collect();
        GC.WaitForPendingFinalizers();

        // B now eligible for collection, but A is not
        if (RefA != null)
            Console.WriteLine("RefA is not null");
    }
}

Dans le programme ci-dessus, si le garbage collector choisit d’exécuter le destructeur de A avant le destructeur de B, la sortie de ce programme peut être :In the above program, if the garbage collector chooses to run the destructor of A before the destructor of B, then the output of this program might be:

Destruct instance of A
Destruct instance of B
A.F
RefA is not null

Notez que même si l’instance de A n’était pas utilisée et que le destructeur de Aa été exécuté, il est toujours possible pour les méthodes de A (dans ce cas, F) d’être appelées à partir d’un autre destructeur.Note that although the instance of A was not in use and A's destructor was run, it is still possible for methods of A (in this case, F) to be called from another destructor. Notez également que l’exécution d’un destructeur peut entraîner la réutilisation d’un objet à partir du programme principal.Also, note that running of a destructor may cause an object to become usable from the mainline program again. Dans ce cas, l’exécution du destructeur de Ba entraîné une instance de A qui n’était pas utilisée précédemment pour devenir accessible à partir de la référence active Test.RefA.In this case, the running of B's destructor caused an instance of A that was previously not in use to become accessible from the live reference Test.RefA. Après l’appel à WaitForPendingFinalizers, l’instance de B est éligible pour la collection, mais l’instance de A n’est pas, en raison de la Test.RefAde référence.After the call to WaitForPendingFinalizers, the instance of B is eligible for collection, but the instance of A is not, because of the reference Test.RefA.

Pour éviter toute confusion et un comportement inattendu, il est généralement judicieux que les destructeurs effectuent uniquement un nettoyage sur les données stockées dans les champs de leur propre objet, et non sur les objets référencés ou les champs statiques.To avoid confusion and unexpected behavior, it is generally a good idea for destructors to only perform cleanup on data stored in their object's own fields, and not to perform any actions on referenced objects or static fields.

Une alternative à l’utilisation des destructeurs consiste à permettre à une classe d’implémenter l’interface System.IDisposable.An alternative to using destructors is to let a class implement the System.IDisposable interface. Cela permet au client de l’objet de déterminer quand libérer les ressources de l’objet, en généralement en accédant à l’objet en tant que ressource dans une instruction using (instruction using).This allows the client of the object to determine when to release the resources of the object, typically by accessing the object as a resource in a using statement (The using statement).

Ordre d’exécutionExecution order

L’exécution d' C# un programme continue de telle sorte que les effets secondaires de chaque thread d’exécution soient conservés aux points d’exécution critiques.Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. Un effet secondaire est défini comme une lecture ou une écriture d’un champ volatile, une écriture dans une variable non volatile, une écriture dans une ressource externe et la levée d’une exception.A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write to an external resource, and the throwing of an exception. Les points d’exécution critiques à partir desquels l’ordre de ces effets secondaires doivent être préservés sont des références à des champs volatils (champs volatils), des instructions lock (instruction lock) et la création et l’arrêt des threads.The critical execution points at which the order of these side effects must be preserved are references to volatile fields (Volatile fields), lock statements (The lock statement), and thread creation and termination. L’environnement d’exécution est libre de modifier l’ordre d’exécution d' C# un programme, selon les contraintes suivantes :The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

  • La dépendance des données est conservée dans un thread d’exécution.Data dependence is preserved within a thread of execution. Autrement dit, la valeur de chaque variable est calculée comme si toutes les instructions du thread étaient exécutées dans l’ordre du programme d’origine.That is, the value of each variable is computed as if all statements in the thread were executed in original program order.
  • Les règles de classement d’initialisation sont conservées (initialisation de champ et initialiseurs de variable).Initialization ordering rules are preserved (Field initialization and Variable initializers).
  • L’ordre des effets secondaires est préservé en ce qui concerne les lectures et les écritures volatiles (champs volatiles).The ordering of side effects is preserved with respect to volatile reads and writes (Volatile fields). En outre, l’environnement d’exécution n’a pas besoin d’évaluer une partie d’une expression s’il peut déduire que la valeur de cette expression n’est pas utilisée et qu’aucun effet secondaire nécessaire n’est produit (y compris les effets causés par l’appel d’une méthode ou l’accès à un champ volatile).Additionally, the execution environment need not evaluate part of an expression if it can deduce that that expression's value is not used and that no needed side effects are produced (including any caused by calling a method or accessing a volatile field). Lorsque l’exécution du programme est interrompue par un événement asynchrone (par exemple, une exception levée par un autre thread), il n’est pas garanti que les effets secondaires observables sont visibles dans l’ordre du programme d’origine.When program execution is interrupted by an asynchronous event (such as an exception thrown by another thread), it is not guaranteed that the observable side effects are visible in the original program order.