Structure lexicaleLexical structure

ProgramsPrograms

Un C# programme se compose d’un ou de plusieurs fichiers sources, connus sous le nom d' unités de compilation (unités de compilation).A C# program consists of one or more source files, known formally as compilation units (Compilation units). Un fichier source est une séquence ordonnée de caractères Unicode.A source file is an ordered sequence of Unicode characters. Les fichiers sources ont généralement une correspondance un-à-un avec les fichiers dans un système de fichiers, mais cette correspondance n’est pas nécessaire.Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. Pour une portabilité maximale, il est recommandé d’encoder les fichiers d’un système de fichiers avec l’encodage UTF-8.For maximal portability, it is recommended that files in a file system be encoded with the UTF-8 encoding.

Conceptuellement, un programme est compilé à l’aide de trois étapes :Conceptually speaking, a program is compiled using three steps:

  1. Transformation, qui convertit un fichier d’un répertoire de caractères particulier et d’un schéma d’encodage en une séquence de caractères Unicode.Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters.
  2. Analyse lexicale, qui convertit un flux de caractères d’entrée Unicode en un flux de jetons.Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens.
  3. Analyse syntaxique, qui convertit le flux de jetons en code exécutable.Syntactic analysis, which translates the stream of tokens into executable code.

GrammairesGrammars

Cette spécification présente la syntaxe du langage C# de programmation à l’aide de deux grammaires.This specification presents the syntax of the C# programming language using two grammars. La grammaire lexicale (grammaire lexicale) définit la combinaison des caractères Unicode avec les indicateurs de fin de ligne, les espaces blancs, les commentaires, les jetons et les directives de pré-traitement.The lexical grammar (Lexical grammar) defines how Unicode characters are combined to form line terminators, white space, comments, tokens, and pre-processing directives. La grammaire syntaxique (syntaxe syntaxique) définit la façon dont les jetons résultant de la grammaire lexicale sont combinés C# pour former des programmes.The syntactic grammar (Syntactic grammar) defines how the tokens resulting from the lexical grammar are combined to form C# programs.

Notation grammaticaleGrammar notation

Les grammaires lexicales et syntaxiques sont présentées dans la forme Backus-Naur à l’aide de la notation de l’outil de grammaire ANTLR.The lexical and syntactic grammars are presented in Backus-Naur form using the notation of the ANTLR grammar tool.

Grammaire lexicaleLexical grammar

La grammaire lexicale C# de est présentée dans l' analyse lexicale, les jetonset les directives de pré-traitement.The lexical grammar of C# is presented in Lexical analysis, Tokens, and Pre-processing directives. Les symboles terminaux de la grammaire lexicale sont les caractères du jeu de caractères Unicode, tandis que la grammaire lexicale spécifie la manière dont les caractères sont combinés pour former des jetons (jetons), un espace blanc (espace blanc), des commentaires (Commentaires) et directives de prétraitement (directives de pré-traitement).The terminal symbols of the lexical grammar are the characters of the Unicode character set, and the lexical grammar specifies how characters are combined to form tokens (Tokens), white space (White space), comments (Comments), and pre-processing directives (Pre-processing directives).

Chaque fichier source d’un C# programme doit être conforme à la production d’entrée de la grammaire lexicale (analyse lexicale).Every source file in a C# program must conform to the input production of the lexical grammar (Lexical analysis).

Syntaxe syntaxiqueSyntactic grammar

La grammaire syntaxique de C# est présentée dans les chapitres et les annexes qui suivent ce chapitre.The syntactic grammar of C# is presented in the chapters and appendices that follow this chapter. Les symboles terminaux de la grammaire syntaxique sont les jetons définis par la grammaire lexicale, et la grammaire syntaxique spécifie la manière dont les jetons sont C# combinés pour former des programmes.The terminal symbols of the syntactic grammar are the tokens defined by the lexical grammar, and the syntactic grammar specifies how tokens are combined to form C# programs.

Chaque fichier source d’un C# programme doit se conformer à la production compilation_unit de la grammaire syntaxique (unités de compilation).Every source file in a C# program must conform to the compilation_unit production of the syntactic grammar (Compilation units).

Analyse lexicaleLexical analysis

La production d’entrée définit la structure lexicale C# d’un fichier source.The input production defines the lexical structure of a C# source file. Chaque fichier source d’un C# programme doit se conformer à cette production grammaticale lexicale.Each source file in a C# program must conform to this lexical grammar production.

input
    : input_section?
    ;

input_section
    : input_section_part+
    ;

input_section_part
    : input_element* new_line
    | pp_directive
    ;

input_element
    : whitespace
    | comment
    | token
    ;

Cinq éléments de base composent la structure lexicale d’un C# fichier source : Marques de fin de ligne (indicateurs de fin de ligne), espace blanc (espace blanc), commentaires (Commentaires), jetons (jetons) et directives de prétraitement (directives de pré-traitement).Five basic elements make up the lexical structure of a C# source file: Line terminators (Line terminators), white space (White space), comments (Comments), tokens (Tokens), and pre-processing directives (Pre-processing directives). Parmi ces éléments de base, seuls les jetons sont significatifs dans la grammaire syntaxique C# d’un programme (syntaxesyntaxique).Of these basic elements, only tokens are significant in the syntactic grammar of a C# program (Syntactic grammar).

Le traitement lexical d’un C# fichier source consiste à réduire le fichier en une séquence de jetons qui devient l’entrée de l’analyse syntaxique.The lexical processing of a C# source file consists of reducing the file into a sequence of tokens which becomes the input to the syntactic analysis. Les indicateurs de fin de ligne, les espaces blancs et les commentaires peuvent servir à séparer les jetons, et les directives de prétraitement peuvent entraîner l’omission des sections du fichier source, mais ces éléments lexicaux n’ont aucun impact sur la structure C# syntaxique d’un programme.Line terminators, white space, and comments can serve to separate tokens, and pre-processing directives can cause sections of the source file to be skipped, but otherwise these lexical elements have no impact on the syntactic structure of a C# program.

Dans le cas de littéraux de chaîne interpolés (littéraux de chaîne interpolés), un seul jeton est initialement généré par l’analyse lexicale, mais il est divisé en plusieurs éléments d’entrée qui sont soumis à l’analyse lexicale de manière répétée jusqu’à ce que toutes les interpolations les littéraux de chaîne ont été résolus.In the case of interpolated string literals (Interpolated string literals) a single token is initially produced by lexical analysis, but is broken up into several input elements which are repeatedly subjected to lexical analysis until all interpolated string literals have been resolved. Les jetons résultants servent ensuite d’entrée à l’analyse syntaxique.The resulting tokens then serve as input to the syntactic analysis.

Lorsque plusieurs productions grammaticales lexicales correspondent à une séquence de caractères dans un fichier source, le traitement lexical forme toujours l’élément lexical le plus long possible.When several lexical grammar productions match a sequence of characters in a source file, the lexical processing always forms the longest possible lexical element. Par exemple, la séquence // de caractères est traitée comme le début d’un commentaire sur une seule ligne, car cet élément lexical est plus long qu’un seul / jeton.For example, the character sequence // is processed as the beginning of a single-line comment because that lexical element is longer than a single / token.

Marques de fin de ligneLine terminators

Les marques de fin de ligne divisent les caractères d’un C# fichier source en lignes.Line terminators divide the characters of a C# source file into lines.

new_line
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Carriage return character (U+000D) followed by line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

Pour la compatibilité avec les outils d’édition de code source qui ajoutent des marqueurs de fin de fichier et pour permettre à un fichier source d’être affiché sous la forme d’une séquence de lignes correctement terminées, les transformations suivantes sont appliquées, C# dans l’ordre, à chaque fichier source d’un programme :For compatibility with source code editing tools that add end-of-file markers, and to enable a source file to be viewed as a sequence of properly terminated lines, the following transformations are applied, in order, to every source file in a C# program:

  • Si le dernier caractère du fichier source est un caractère de contrôle Z (U+001A), ce caractère est supprimé.If the last character of the source file is a Control-Z character (U+001A), this character is deleted.
  • Un caractère de retour chariot (U+000D) est ajouté à la fin du fichier source si ce fichier source n’est pas vide et si le dernier caractère du fichier source n’est pas un retour chariot (U+000D), un saut de ligne (U+000A), un séparateur de ligne (U+2028) ou un séparateur de paragraphe (U+2029).A carriage-return character (U+000D) is added to the end of the source file if that source file is non-empty and if the last character of the source file is not a carriage return (U+000D), a line feed (U+000A), a line separator (U+2028), or a paragraph separator (U+2029).

CommentairesComments

Deux formes de commentaires sont pris en charge : commentaires sur une seule ligne et commentaires délimités.Two forms of comments are supported: single-line comments and delimited comments. Les Commentaires sur une seule ligne commencent par // les caractères et s’étendent jusqu’à la fin de la ligne source.Single-line comments start with the characters // and extend to the end of the source line. Les Commentaires délimités commencent par /* les caractères et se terminent par les caractères. */Delimited comments start with the characters /* and end with the characters */. Les commentaires délimités peuvent s’étendre sur plusieurs lignes.Delimited comments may span multiple lines.

comment
    : single_line_comment
    | delimited_comment
    ;

single_line_comment
    : '//' input_character*
    ;

input_character
    : '<Any Unicode character except a new_line_character>'
    ;

new_line_character
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

delimited_comment
    : '/*' delimited_comment_section* asterisk+ '/'
    ;

delimited_comment_section
    : '/'
    | asterisk* not_slash_or_asterisk
    ;

asterisk
    : '*'
    ;

not_slash_or_asterisk
    : '<Any Unicode character except / or *>'
    ;

Les commentaires ne sont pas imbriqués.Comments do not nest. /* Les séquences de caractères */ et n’ont aucune signification particulière // dans un commentaire, et les séquences /* // de caractères et n’ont aucune signification particulière dans un commentaire délimité.The character sequences /* and */ have no special meaning within a // comment, and the character sequences // and /* have no special meaning within a delimited comment.

Les commentaires ne sont pas traités dans des littéraux de chaîne et de caractère.Comments are not processed within character and string literals.

L’exempleThe example

/* Hello, world program
   This program writes "hello, world" to the console
*/
class Hello
{
    static void Main() {
        System.Console.WriteLine("hello, world");
    }
}

comprend un commentaire délimité.includes a delimited comment.

L’exempleThe example

// Hello, world program
// This program writes "hello, world" to the console
//
class Hello // any name will do for this class
{
    static void Main() { // this method must be named "Main"
        System.Console.WriteLine("hello, world");
    }
}

affiche plusieurs commentaires sur une seule ligne.shows several single-line comments.

Espace blancWhite space

Un espace blanc est défini comme n’importe quel caractère avec la classe Unicode Zs (qui comprend le caractère espace), ainsi que le caractère de tabulation horizontale, le caractère de tabulation verticale et le caractère de saut de forme.White space is defined as any character with Unicode class Zs (which includes the space character) as well as the horizontal tab character, the vertical tab character, and the form feed character.

whitespace
    : '<Any character with Unicode class Zs>'
    | '<Horizontal tab character (U+0009)>'
    | '<Vertical tab character (U+000B)>'
    | '<Form feed character (U+000C)>'
    ;

jetonsTokens

Il existe plusieurs genres de jetons : les identificateurs, les mots clés, les littéraux, les opérateurs et les signes de ponctuation.There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators. Les espaces blancs et les commentaires ne sont pas des jetons, bien qu’ils agissent comme séparateurs pour les jetons.White space and comments are not tokens, though they act as separators for tokens.

token
    : identifier
    | keyword
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | interpolated_string_literal
    | operator_or_punctuator
    ;

Séquences d’échappement de caractères UnicodeUnicode character escape sequences

Une séquence d’échappement de caractère Unicode représente un caractère Unicode.A Unicode character escape sequence represents a Unicode character. Les séquences d’échappement de caractères Unicode sont traitées dans les identificateurs (identificateurs), les littéraux de caractère (littéraux de caractère) et les littéraux de chaîne normaux (littéraux de chaîne).Unicode character escape sequences are processed in identifiers (Identifiers), character literals (Character literals), and regular string literals (String literals). Un caractère d’échappement Unicode n’est pas traité à un autre emplacement (par exemple, pour former un opérateur, un signe de ponctuation ou un mot clé).A Unicode character escape is not processed in any other location (for example, to form an operator, punctuator, or keyword).

unicode_escape_sequence
    : '\\u' hex_digit hex_digit hex_digit hex_digit
    | '\\U' hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
    ;

Une séquence d’échappement Unicode représente le caractère Unicode unique formé par le nombre hexadécimal suivant les\ucaractères « »\Uou « ».A Unicode escape sequence represents the single Unicode character formed by the hexadecimal number following the "\u" or "\U" characters. Étant C# donné que utilise un encodage 16 bits de points de code Unicode en caractères et des valeurs de chaîne, un caractère Unicode dans la plage comprise entre u + 10000 et u + 10FFFF n’est pas autorisé dans un littéral de caractère et est représenté à l’aide d’une paire de substitution Unicode dans un littéral de chaîne.Since C# uses a 16-bit encoding of Unicode code points in characters and string values, a Unicode character in the range U+10000 to U+10FFFF is not permitted in a character literal and is represented using a Unicode surrogate pair in a string literal. Les caractères Unicode avec des points de code au-dessus de 0x10FFFF ne sont pas pris en charge.Unicode characters with code points above 0x10FFFF are not supported.

Plusieurs traductions ne sont pas effectuées.Multiple translations are not performed. Par exemple, le littéral de chaîne\u005Cu005C« » est équivalent à\u005C« » plutôt qu'\à «».For instance, the string literal "\u005Cu005C" is equivalent to "\u005C" rather than "\". La valeur \u005C Unicode est le caractère «\».The Unicode value \u005C is the character "\".

L’exempleThe example

class Class1
{
    static void Test(bool \u0066) {
        char c = '\u0066';
        if (\u0066)
            System.Console.WriteLine(c.ToString());
    }        
}

montre plusieurs utilisations de \u0066, qui est la séquence d’échappement pour la lettref«».shows several uses of \u0066, which is the escape sequence for the letter "f". Le programme est équivalent àThe program is equivalent to

class Class1
{
    static void Test(bool f) {
        char c = 'f';
        if (f)
            System.Console.WriteLine(c.ToString());
    }        
}

IdentificateursIdentifiers

Les règles relatives aux identificateurs fournis dans cette section correspondent exactement à celles recommandées par la norme Unicode annexe 31, sauf que le trait de soulignement est autorisé comme caractère initial (comme c’est le cas dans le langage de programmation C), les séquences d’échappement Unicode sont autorisé dans les identificateurs, et le@caractère «» est autorisé en tant que préfixe pour permettre l’utilisation de mots clés comme identificateurs.The rules for identifiers given in this section correspond exactly to those recommended by the Unicode Standard Annex 31, except that underscore is allowed as an initial character (as is traditional in the C programming language), Unicode escape sequences are permitted in identifiers, and the "@" character is allowed as a prefix to enable keywords to be used as identifiers.

identifier
    : available_identifier
    | '@' identifier_or_keyword
    ;

available_identifier
    : '<An identifier_or_keyword that is not a keyword>'
    ;

identifier_or_keyword
    : identifier_start_character identifier_part_character*
    ;

identifier_start_character
    : letter_character
    | '_'
    ;

identifier_part_character
    : letter_character
    | decimal_digit_character
    | connecting_character
    | combining_character
    | formatting_character
    ;

letter_character
    : '<A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    | '<A unicode_escape_sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    ;

combining_character
    : '<A Unicode character of classes Mn or Mc>'
    | '<A unicode_escape_sequence representing a character of classes Mn or Mc>'
    ;

decimal_digit_character
    : '<A Unicode character of the class Nd>'
    | '<A unicode_escape_sequence representing a character of the class Nd>'
    ;

connecting_character
    : '<A Unicode character of the class Pc>'
    | '<A unicode_escape_sequence representing a character of the class Pc>'
    ;

formatting_character
    : '<A Unicode character of the class Cf>'
    | '<A unicode_escape_sequence representing a character of the class Cf>'
    ;

Pour plus d’informations sur les classes de caractères Unicode mentionnées ci-dessus, consultez la norme Unicode, version 3,0, section 4,5.For information on the Unicode character classes mentioned above, see The Unicode Standard, Version 3.0, section 4.5.

«identifier1», «_identifier2» Et «@if» sont des exemples d’identificateurs valides.Examples of valid identifiers include "identifier1", "_identifier2", and "@if".

Un identificateur dans un programme conforme doit être au format canonique défini par le formulaire de normalisation Unicode C, comme défini par la norme Unicode annexe 15.An identifier in a conforming program must be in the canonical format defined by Unicode Normalization Form C, as defined by Unicode Standard Annex 15. Le comportement lors de la rencontre d’un identificateur qui ne figure pas dans le formulaire de normalisation C est défini par l’implémentation ; Toutefois, aucun diagnostic n’est nécessaire.The behavior when encountering an identifier not in Normalization Form C is implementation-defined; however, a diagnostic is not required.

Le préfixe@«» permet d’utiliser des mots clés en tant qu’identificateurs, ce qui est utile lors de l’interfaçage avec d’autres langages de programmation.The prefix "@" enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. Le caractère @ ne faisant pas réellement partie de l’identificateur, l’identificateur peut être vu dans d’autres langages comme un identificateur normal, sans le préfixe.The character @ is not actually part of the identifier, so the identifier might be seen in other languages as a normal identifier, without the prefix. Un identificateur avec un @ préfixe est appelé identificateur textuel.An identifier with an @ prefix is called a verbatim identifier. L’utilisation du @ préfixe pour les identificateurs qui ne sont pas des mots clés est autorisée, mais elle est fortement déconseillée comme une question de style.Use of the @ prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style.

L’exemple suivant :The example:

class @class
{
    public static void @static(bool @bool) {
        if (@bool)
            System.Console.WriteLine("true");
        else
            System.Console.WriteLine("false");
    }    
}

class Class1
{
    static void M() {
        cl\u0061ss.st\u0061tic(true);
    }
}

définit une classe nommée «class» avec une méthode statique nommée «static» qui prend un paramètre nommé «bool».defines a class named "class" with a static method named "static" that takes a parameter named "bool". Notez que dans la mesure où les échappements Unicode ne sont pas autorisés danscl\u0061ssles mots clés, le jeton « » est un identificateur et est le@classmême identificateur que « ».Note that since Unicode escapes are not permitted in keywords, the token "cl\u0061ss" is an identifier, and is the same identifier as "@class".

Deux identificateurs sont considérés comme identiques s’ils sont identiques après l’application des transformations suivantes, dans l’ordre :Two identifiers are considered the same if they are identical after the following transformations are applied, in order:

  • Le préfixe@«», s’il est utilisé, est supprimé.The prefix "@", if used, is removed.
  • Chaque unicode_escape_sequence est transformée en son caractère Unicode correspondant.Each unicode_escape_sequence is transformed into its corresponding Unicode character.
  • Tous les formatting_charactersont supprimés.Any formatting_characters are removed.

Les identificateurs contenant deux traits de soulignement consécutifs (U+005F) sont réservés pour une utilisation par l’implémentation.Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation. Par exemple, une implémentation peut fournir des mots clés étendus qui commencent par deux traits de soulignement.For example, an implementation might provide extended keywords that begin with two underscores.

Mots clésKeywords

Un mot clé est une séquence de caractères de type identificateur, qui est réservée et ne peut pas être utilisée en tant qu’identificateur, sauf s’il @ est précédé du caractère.A keyword is an identifier-like sequence of characters that is reserved, and cannot be used as an identifier except when prefaced by the @ character.

keyword
    : 'abstract' | 'as'       | 'base'       | 'bool'      | 'break'
    | 'byte'     | 'case'     | 'catch'      | 'char'      | 'checked'
    | 'class'    | 'const'    | 'continue'   | 'decimal'   | 'default'
    | 'delegate' | 'do'       | 'double'     | 'else'      | 'enum'
    | 'event'    | 'explicit' | 'extern'     | 'false'     | 'finally'
    | 'fixed'    | 'float'    | 'for'        | 'foreach'   | 'goto'
    | 'if'       | 'implicit' | 'in'         | 'int'       | 'interface'
    | 'internal' | 'is'       | 'lock'       | 'long'      | 'namespace'
    | 'new'      | 'null'     | 'object'     | 'operator'  | 'out'
    | 'override' | 'params'   | 'private'    | 'protected' | 'public'
    | 'readonly' | 'ref'      | 'return'     | 'sbyte'     | 'sealed'
    | 'short'    | 'sizeof'   | 'stackalloc' | 'static'    | 'string'
    | 'struct'   | 'switch'   | 'this'       | 'throw'     | 'true'
    | 'try'      | 'typeof'   | 'uint'       | 'ulong'     | 'unchecked'
    | 'unsafe'   | 'ushort'   | 'using'      | 'virtual'   | 'void'
    | 'volatile' | 'while'
    ;

À certains endroits de la grammaire, les identificateurs spécifiques ont une signification particulière, mais ne sont pas des mots clés.In some places in the grammar, specific identifiers have special meaning, but are not keywords. Ces identificateurs sont parfois appelés « Mots-clés contextuels ».Such identifiers are sometimes referred to as "contextual keywords". Par exemple, dans une déclaration de propriété, lesgetidentificateurs «set» et «» ont une signification spéciale (accesseurs).For example, within a property declaration, the "get" and "set" identifiers have special meaning (Accessors). Comme un identificateur autre que get ou set n’est jamais autorisé dans ces emplacements, cette utilisation n’est pas en conflit avec l’utilisation de ces mots comme identificateurs.An identifier other than get or set is never permitted in these locations, so this use does not conflict with a use of these words as identifiers. Dans d’autres cas, comme avec l’identificateur «var» dans les déclarations de variables locales implicitement typées (déclarations devariables locales), un mot clé contextuel peut être en conflit avec des noms déclarés.In other cases, such as with the identifier "var" in implicitly typed local variable declarations (Local variable declarations), a contextual keyword can conflict with declared names. Dans ce cas, le nom déclaré est prioritaire par rapport à l’utilisation de l’identificateur en tant que mot clé contextuel.In such cases, the declared name takes precedence over the use of the identifier as a contextual keyword.

LittérauxLiterals

Un littéral est une représentation du code source d’une valeur.A literal is a source code representation of a value.

literal
    : boolean_literal
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | null_literal
    ;

Littéraux booléensBoolean literals

Il existe deux valeurs littérales booléennes false: true et.There are two boolean literal values: true and false.

boolean_literal
    : 'true'
    | 'false'
    ;

Le type d’un boolean_literal est bool.The type of a boolean_literal is bool.

Littéraux d'entierInteger literals

Les littéraux entiers sont utilisés pour écrire des intvaleurs uintde longtypes, ulong, et.Integer literals are used to write values of types int, uint, long, and ulong. Les littéraux entiers ont deux formes possibles : decimal et hexadécimal.Integer literals have two possible forms: decimal and hexadecimal.

integer_literal
    : decimal_integer_literal
    | hexadecimal_integer_literal
    ;

decimal_integer_literal
    : decimal_digit+ integer_type_suffix?
    ;

decimal_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    ;

integer_type_suffix
    : 'U' | 'u' | 'L' | 'l' | 'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
    ;

hexadecimal_integer_literal
    : '0x' hex_digit+ integer_type_suffix?
    | '0X' hex_digit+ integer_type_suffix?
    ;

hex_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';

Le type d’un littéral entier est déterminé comme suit :The type of an integer literal is determined as follows:

  • Si le littéral n’a pas de suffixe, il a le premier de ces types dans lequel sa valeur peut intêtre uintreprésentée : ulong,, long,.If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
  • Si le littéral est suivi d’un U suffixe par ou u, il a le premier de ces types dans lequel sa valeur peut uintêtre ulongreprésentée :,.If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.
  • Si le littéral est suivi d’un L suffixe par ou l, il a le premier de ces types dans lequel sa valeur peut longêtre ulongreprésentée :,.If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong.
  • Si le littéral est précédé ULd’un suffixe, ul Ul, LU uL, Lu, lU,, luou, il est de ulongtype.If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.

Si la valeur représentée par un littéral entier est en dehors de la plage ulong du type, une erreur de compilation se produit.If the value represented by an integer literal is outside the range of the ulong type, a compile-time error occurs.

En guise de style, il est suggéré d’utiliserL« » à la place del« » lors de l’écriture de longlittéraux de type, car il est facile de confondre la lettre «1``l» avec le chiffre «».As a matter of style, it is suggested that "L" be used instead of "l" when writing literals of type long, since it is easy to confuse the letter "l" with the digit "1".

Pour que les valeurs int et long les plus petites soient écrites en tant que littéraux décimaux entiers, les deux règles suivantes existent :To permit the smallest possible int and long values to be written as decimal integer literals, the following two rules exist:

  • Lorsqu’un decimal_integer_literal avec la valeur 2147483648 (2 ^ 31) et qu’aucun integer_type_suffix n’apparaît en tant que jeton qui suit immédiatement un jeton d’opérateur moins unaire (opérateur moins unaire), le résultat est une constante de type int avec la valeur-2147483648 (-2 ^ 31).When a decimal_integer_literal with the value 2147483648 (2^31) and no integer_type_suffix appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type int with the value -2147483648 (-2^31). Dans toutes les autres situations, une telle decimal_integer_literal est de type uint.In all other situations, such a decimal_integer_literal is of type uint.
  • Lorsqu’un decimal_integer_literal avec la valeur 9223372036854775808 (2 ^ 63) et aucun integer_type_suffix ou integer_type_suffix L ou l apparaît en tant que jeton qui suit immédiatement un jeton d’opérateur moins unaire ( Opérateur moins unaire), le résultat est une constante de type long avec la valeur-9223372036854775808 (-2 ^ 63).When a decimal_integer_literal with the value 9223372036854775808 (2^63) and no integer_type_suffix or the integer_type_suffix L or l appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type long with the value -9223372036854775808 (-2^63). Dans toutes les autres situations, une telle decimal_integer_literal est de type ulong.In all other situations, such a decimal_integer_literal is of type ulong.

Littéraux réelsReal literals

Les littéraux réels sont utilisés pour écrire des valeurs floatde doubletypes, decimalet.Real literals are used to write values of types float, double, and decimal.

real_literal
    : decimal_digit+ '.' decimal_digit+ exponent_part? real_type_suffix?
    | '.' decimal_digit+ exponent_part? real_type_suffix?
    | decimal_digit+ exponent_part real_type_suffix?
    | decimal_digit+ real_type_suffix
    ;

exponent_part
    : 'e' sign? decimal_digit+
    | 'E' sign? decimal_digit+
    ;

sign
    : '+'
    | '-'
    ;

real_type_suffix
    : 'F' | 'f' | 'D' | 'd' | 'M' | 'm'
    ;

Si aucun real_type_suffix n’est spécifié, le type du littéral réel est double.If no real_type_suffix is specified, the type of the real literal is double. Dans le cas contraire, le suffixe de type réel détermine le type du littéral réel, comme suit :Otherwise, the real type suffix determines the type of the real literal, as follows:

  • Littéral réel dont le suffixe F est f ou est de floattype.A real literal suffixed by F or f is of type float. Par exemple, les littéraux 1f, 1.5f, 1e10fet 123.456F sont tous de type float.For example, the literals 1f, 1.5f, 1e10f, and 123.456F are all of type float.
  • Littéral réel dont le suffixe D est d ou est de doubletype.A real literal suffixed by D or d is of type double. Par exemple, les littéraux 1d, 1.5d, 1e10det 123.456D sont tous de type double.For example, the literals 1d, 1.5d, 1e10d, and 123.456D are all of type double.
  • Littéral réel dont le suffixe M est m ou est de decimaltype.A real literal suffixed by M or m is of type decimal. Par exemple, les littéraux 1m, 1.5m, 1e10met 123.456M sont tous de type decimal.For example, the literals 1m, 1.5m, 1e10m, and 123.456M are all of type decimal. Ce littéral est converti en une decimal valeur en acceptant la valeur exacte et, si nécessaire, en arrondissant à la valeur représentable la plus proche à l’aide de l’arrondi de Banker (type décimal).This literal is converted to a decimal value by taking the exact value, and, if necessary, rounding to the nearest representable value using banker's rounding (The decimal type). Toute échelle apparente dans le littéral est conservée, sauf si la valeur est arrondie ou si la valeur est égale à zéro (dans ce dernier cas, le signe et l’échelle sont 0).Any scale apparent in the literal is preserved unless the value is rounded or the value is zero (in which latter case the sign and scale will be 0). Par conséquent, le 2.900m littéral sera analysé pour former la décimale avec le 0signe, le 2900coefficient et 3l’échelle.Hence, the literal 2.900m will be parsed to form the decimal with sign 0, coefficient 2900, and scale 3.

Si le littéral spécifié ne peut pas être représenté dans le type indiqué, une erreur de compilation se produit.If the specified literal cannot be represented in the indicated type, a compile-time error occurs.

La valeur d’un littéral réel de type float ou double est déterminée à l’aide du mode IEEE « arrondi au plus proche ».The value of a real literal of type float or double is determined by using the IEEE "round to nearest" mode.

Notez que dans un littéral réel, les chiffres décimaux sont toujours requis après la virgule décimale.Note that in a real literal, decimal digits are always required after the decimal point. Par exemple, 1.3F est un littéral réel, 1.F mais pas.For example, 1.3F is a real literal but 1.F is not.

Littéraux de caractèreCharacter literals

Un littéral de caractère représente un caractère unique et se compose généralement d’un caractère entre guillemets, 'a'comme dans.A character literal represents a single character, and usually consists of a character in quotes, as in 'a'.

Remarque : La notation de la grammaire ANTLR rend ce qui est confus.Note: The ANTLR grammar notation makes the following confusing! Dans antlr, lorsque vous écrivez \' , il s’agit d’un 'guillemet simple.In ANTLR, when you write \' it stands for a single quote '. Lorsque vous écrivez \\ , il s’agit d’une barre \oblique inverse unique.And when you write \\ it stands for a single backslash \. Par conséquent, la première règle pour un littéral de caractère signifie qu’il commence par un guillemet simple, puis par un caractère, puis par un guillemet simple.Therefore the first rule for a character literal means it starts with a single quote, then a character, then a single quote. Et les onze séquences d’échappement simples possibles \'sont \", \\, \0, \a, \b, \f, \n, \r, \t, ,\v.And the eleven possible simple escape sequences are \', \", \\, \0, \a, \b, \f, \n, \r, \t, \v.

character_literal
    : '\'' character '\''
    ;

character
    : single_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_character
    : '<Any character except \' (U+0027), \\ (U+005C), and new_line_character>'
    ;

simple_escape_sequence
    : '\\\'' | '\\"' | '\\\\' | '\\0' | '\\a' | '\\b' | '\\f' | '\\n' | '\\r' | '\\t' | '\\v'
    ;

hexadecimal_escape_sequence
    : '\\x' hex_digit hex_digit? hex_digit? hex_digit?;

Un caractère qui suit une barre oblique inverse\() dans un caractère doit être l’un des caractères suivants ': ", \, 0, a, b, f , , n, r, t, u, U, x, v.A character that follows a backslash character (\) in a character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Sinon, une erreur de compilation se produit.Otherwise, a compile-time error occurs.

Une séquence d’échappement hexadécimale représente un caractère Unicode unique, avec la valeur formée par le nombre hexadécimal\xsuivant «».A hexadecimal escape sequence represents a single Unicode character, with the value formed by the hexadecimal number following "\x".

Si la valeur représentée par un littéral de caractère est supérieure U+FFFFà, une erreur de compilation se produit.If the value represented by a character literal is greater than U+FFFF, a compile-time error occurs.

Une séquence d’échappement de caractère Unicode (séquences d’échappement de caractère Unicode) dans un littéral de caractère U+0000 doit U+FFFFêtre comprise dans la plage de.A Unicode character escape sequence (Unicode character escape sequences) in a character literal must be in the range U+0000 to U+FFFF.

Une séquence d’échappement simple représente un encodage de caractères Unicode, comme décrit dans le tableau ci-dessous.A simple escape sequence represents a Unicode character encoding, as described in the table below.

Séquence d’échappementEscape sequence Nom de caractèreCharacter name Encodage UnicodeUnicode encoding
\' Guillemet simpleSingle quote 0x0027
\" Guillemet doubleDouble quote 0x0022
\\ Barre oblique inverseBackslash 0x005C
\0 NullNull 0x0000
\a AlerteAlert 0x0007
\b Retour arrièreBackspace 0x0008
\f Saut de pageForm feed 0x000C
\n Nouvelle ligneNew line 0x000A
\r Retour chariotCarriage return 0x000D
\t Tabulation horizontaleHorizontal tab 0x0009
\v Tabulation verticaleVertical tab 0x000B

Le type d’un character_literal est char.The type of a character_literal is char.

Littéraux de chaîneString literals

C#prend en charge deux formes de littéraux de chaîne : les littéraux de chaîne normaux et les littéraux de chaîne Verbatim.C# supports two forms of string literals: regular string literals and verbatim string literals.

Un littéral de chaîne standard se compose de zéro, un ou plusieurs caractères placés entre guillemets doubles, comme dans "hello", et peut inclure à la fois des séquences d’échappement simples (comme \t pour le caractère de tabulation) et des séquences d’échappement hexadécimales et Unicode.A regular string literal consists of zero or more characters enclosed in double quotes, as in "hello", and may include both simple escape sequences (such as \t for the tab character), and hexadecimal and Unicode escape sequences.

Un littéral de chaîne Verbatim se compose @ d’un caractère suivi d’un guillemet double, de zéro, d’un ou de plusieurs caractères et d’un guillemet double fermant.A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. Un exemple simple est @"hello".A simple example is @"hello". Dans un littéral de chaîne Verbatim, les caractères entre les délimiteurs sont interprétés textuellement, la seule exception étant quote_escape_sequence.In a verbatim string literal, the characters between the delimiters are interpreted verbatim, the only exception being a quote_escape_sequence. En particulier, les séquences d’échappement simples et les séquences d’échappement hexadécimales et Unicode ne sont pas traitées dans des littéraux de chaîne Verbatim.In particular, simple escape sequences, and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. Un littéral de chaîne Verbatim peut s’étendre sur plusieurs lignes.A verbatim string literal may span multiple lines.

string_literal
    : regular_string_literal
    | verbatim_string_literal
    ;

regular_string_literal
    : '"' regular_string_literal_character* '"'
    ;

regular_string_literal_character
    : single_regular_string_literal_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_regular_string_literal_character
    : '<Any character except " (U+0022), \\ (U+005C), and new_line_character>'
    ;

verbatim_string_literal
    : '@"' verbatim_string_literal_character* '"'
    ;

verbatim_string_literal_character
    : single_verbatim_string_literal_character
    | quote_escape_sequence
    ;

single_verbatim_string_literal_character
    : '<any character except ">'
    ;

quote_escape_sequence
    : '""'
    ;

Un caractère qui suit une barre oblique inverse (\) dans un regular_string_literal_character doit être l’un des caractères suivants : ', ", \, 0, a, b, f, n, 0, 1, @no__ t-12, 3, 4, 5.A character that follows a backslash character (\) in a regular_string_literal_character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Sinon, une erreur de compilation se produit.Otherwise, a compile-time error occurs.

L’exempleThe example

string a = "hello, world";                   // hello, world
string b = @"hello, world";                  // hello, world

string c = "hello \t world";                 // hello      world
string d = @"hello \t world";                // hello \t world

string e = "Joe said \"Hello\" to me";       // Joe said "Hello" to me
string f = @"Joe said ""Hello"" to me";      // Joe said "Hello" to me

string g = "\\\\server\\share\\file.txt";    // \\server\share\file.txt
string h = @"\\server\share\file.txt";       // \\server\share\file.txt

string i = "one\r\ntwo\r\nthree";
string j = @"one
two
three";

affiche divers littéraux de chaîne.shows a variety of string literals. Le dernier littéral de chaîne j,, est un littéral de chaîne Verbatim qui s’étend sur plusieurs lignes.The last string literal, j, is a verbatim string literal that spans multiple lines. Les caractères entre guillemets, y compris les espaces blancs tels que les caractères de nouvelle ligne, sont conservés textuellement.The characters between the quotation marks, including white space such as new line characters, are preserved verbatim.

Comme une séquence d’échappement hexadécimale peut avoir un nombre variable de chiffres hexadécimaux, le "\x123" littéral de chaîne contient un caractère unique avec la valeur hexadécimale 123.Since a hexadecimal escape sequence can have a variable number of hex digits, the string literal "\x123" contains a single character with hex value 123. Pour créer une chaîne contenant le caractère avec la valeur hexadécimale 12 suivi du caractère 3, il est "\x00123" possible "\x12" + "3" d’écrire ou à la place.To create a string containing the character with hex value 12 followed by the character 3, one could write "\x00123" or "\x12" + "3" instead.

Le type d’un string_literal est string.The type of a string_literal is string.

Chaque littéral de chaîne ne produit pas nécessairement une nouvelle instance de chaîne.Each string literal does not necessarily result in a new string instance. Lorsque deux littéraux de chaîne ou plus qui sont équivalents en fonction de l’opérateur d’égalité de chaînes (opérateurs d’égalité de chaînes) apparaissent dans le même programme, ces littéraux de chaîne font référence à la même instance de chaîne.When two or more string literals that are equivalent according to the string equality operator (String equality operators) appear in the same program, these string literals refer to the same string instance. Par exemple, la sortie produite parFor instance, the output produced by

class Test
{
    static void Main() {
        object a = "hello";
        object b = "hello";
        System.Console.WriteLine(a == b);
    }
}

est True dû au fait que les deux littéraux font référence à la même instance de chaîne.is True because the two literals refer to the same string instance.

Littéraux de chaîne interpolésInterpolated string literals

Les littéraux de chaîne interpolés sont similaires aux littéraux de chaîne, mais contiennent des { trous }délimités par et, où les expressions peuvent se produire.Interpolated string literals are similar to string literals, but contain holes delimited by { and }, wherein expressions can occur. Lors de l’exécution, les expressions sont évaluées dans le but de faire en sorte que leurs formes textuelles se substituent à la chaîne à l’endroit où se trouve le trou.At runtime, the expressions are evaluated with the purpose of having their textual forms substituted into the string at the place where the hole occurs. La syntaxe et la sémantique de l’interpolation de chaîne sont décrites dans la section (chaînes interpolées).The syntax and semantics of string interpolation are described in section (Interpolated strings).

À l’instar des littéraux de chaîne, les littéraux de chaîne interpolés peuvent être normaux ou textuels.Like string literals, interpolated string literals can be either regular or verbatim. Les littéraux de chaîne réguliers interpolés sont délimités $" par et ", et les littéraux de chaîne Verbatim interpolés "sont délimités par $@" et.Interpolated regular string literals are delimited by $" and ", and interpolated verbatim string literals are delimited by $@" and ".

Comme pour les autres littéraux, l’analyse lexicale d’un littéral de chaîne interpolée produit initialement un jeton unique, conformément à la grammaire ci-dessous.Like other literals, lexical analysis of an interpolated string literal initially results in a single token, as per the grammar below. Toutefois, avant l’analyse syntaxique, le jeton unique d’un littéral de chaîne interpolé est divisé en plusieurs jetons pour les parties de la chaîne qui entourent les trous, et les éléments d’entrée qui se produisent dans les trous sont analysés de façon lexicale.However, before syntactic analysis, the single token of an interpolated string literal is broken into several tokens for the parts of the string enclosing the holes, and the input elements occurring in the holes are lexically analysed again. Cela peut, à son tour, générer davantage de littéraux de chaîne interpolés à traiter, mais, s’il est correct, finit par entraîner une séquence de jetons pour l’analyse syntaxique.This may in turn produce more interpolated string literals to be processed, but, if lexically correct, will eventually lead to a sequence of tokens for syntactic analysis to process.

interpolated_string_literal
    : '$' interpolated_regular_string_literal
    | '$' interpolated_verbatim_string_literal
    ;

interpolated_regular_string_literal
    : interpolated_regular_string_whole
    | interpolated_regular_string_start  interpolated_regular_string_literal_body interpolated_regular_string_end
    ;

interpolated_regular_string_literal_body
    : regular_balanced_text
    | interpolated_regular_string_literal_body interpolated_regular_string_mid regular_balanced_text
    ;

interpolated_regular_string_whole
    : '"' interpolated_regular_string_character* '"'
    ;

interpolated_regular_string_start
    : '"' interpolated_regular_string_character* '{'
    ;

interpolated_regular_string_mid
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '{'
    ;

interpolated_regular_string_end
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '"'
    ;

interpolated_regular_string_characters_after_brace
    : interpolated_regular_string_character_no_brace
    | interpolated_regular_string_characters_after_brace interpolated_regular_string_character
    ;

interpolated_regular_string_character
    : single_interpolated_regular_string_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;

interpolated_regular_string_character_no_brace
    : '<Any interpolated_regular_string_character except close_brace_escape_sequence and any hexadecimal_escape_sequence or unicode_escape_sequence designating } (U+007D)>'
    ;

single_interpolated_regular_string_character
    : '<Any character except \" (U+0022), \\ (U+005C), { (U+007B), } (U+007D), and new_line_character>'
    ;

open_brace_escape_sequence
    : '{{'
    ;

close_brace_escape_sequence
    : '}}'
    ;
    
regular_balanced_text
    : regular_balanced_text_part+
    ;

regular_balanced_text_part
    : single_regular_balanced_text_character
    | delimited_comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' regular_balanced_text ')'
    | '[' regular_balanced_text ']'
    | '{' regular_balanced_text '}'
    ;
    
single_regular_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B), } (U+007D) and new_line_character>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;
    
interpolation_format
    : interpolation_format_character+
    ;
    
interpolation_format_character
    : '<Any character except \" (U+0022), : (U+003A), { (U+007B) and } (U+007D)>'
    ;
    
interpolated_verbatim_string_literal
    : interpolated_verbatim_string_whole
    | interpolated_verbatim_string_start interpolated_verbatim_string_literal_body interpolated_verbatim_string_end
    ;

interpolated_verbatim_string_literal_body
    : verbatim_balanced_text
    | interpolated_verbatim_string_literal_body interpolated_verbatim_string_mid verbatim_balanced_text
    ;
    
interpolated_verbatim_string_whole
    : '@"' interpolated_verbatim_string_character* '"'
    ;
    
interpolated_verbatim_string_start
    : '@"' interpolated_verbatim_string_character* '{'
    ;
    
interpolated_verbatim_string_mid
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '{'
    ;
    
interpolated_verbatim_string_end
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '"'
    ;
    
interpolated_verbatim_string_characters_after_brace
    : interpolated_verbatim_string_character_no_brace
    | interpolated_verbatim_string_characters_after_brace interpolated_verbatim_string_character
    ;
    
interpolated_verbatim_string_character
    : single_interpolated_verbatim_string_character
    | quote_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;
    
interpolated_verbatim_string_character_no_brace
    : '<Any interpolated_verbatim_string_character except close_brace_escape_sequence>'
    ;
    
single_interpolated_verbatim_string_character
    : '<Any character except \" (U+0022), { (U+007B) and } (U+007D)>'
    ;
    
verbatim_balanced_text
    : verbatim_balanced_text_part+
    ;

verbatim_balanced_text_part
    : single_verbatim_balanced_text_character
    | comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' verbatim_balanced_text ')'
    | '[' verbatim_balanced_text ']'
    | '{' verbatim_balanced_text '}'
    ;
    
single_verbatim_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B) and } (U+007D)>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;

Un jeton interpolated_string_literal est réinterprété comme plusieurs jetons et autres éléments d’entrée comme suit, dans l’ordre des occurrences dans le interpolated_string_literal:An interpolated_string_literal token is reinterpreted as multiple tokens and other input elements as follows, in order of occurrence in the interpolated_string_literal:

  • Les occurrences des éléments suivants sont réinterprétées comme des jetons individuels distincts : le signe $ de début, interpolated_regular_string_whole, interpolated_regular_string_start, interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_whole, interpolated_verbatim_string_start, interpolated_verbatim_string_mid et interpolated_verbatim_string_end.Occurrences of the following are reinterpreted as separate individual tokens: the leading $ sign, interpolated_regular_string_whole, interpolated_regular_string_start, interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_whole, interpolated_verbatim_string_start, interpolated_verbatim_string_mid and interpolated_verbatim_string_end.
  • Les occurrences de regular_balanced_text et verbatim_balanced_text entre celles-ci sont retraitées comme un input_section (analyse lexicale) et sont réinterprétées comme la séquence résultante d’éléments d’entrée.Occurrences of regular_balanced_text and verbatim_balanced_text between these are reprocessed as an input_section (Lexical analysis) and are reinterpreted as the resulting sequence of input elements. Elles peuvent à leur tour inclure des jetons de littéral de chaîne interpolés à réinterpréter.These may in turn include interpolated string literal tokens to be reinterpreted.

L’analyse syntaxique réassociera les jetons en un interpolated_string_expression (chaînes interpolées).Syntactic analysis will recombine the tokens into an interpolated_string_expression (Interpolated strings).

Exemples TODOExamples TODO

Littéral nullThe null literal

null_literal
    : 'null'
    ;

Le null_literal peut être converti implicitement en un type référence ou un type Nullable.The null_literal can be implicitly converted to a reference type or nullable type.

Opérateurs et signes de ponctuationOperators and punctuators

Il existe plusieurs types d’opérateurs et de signes de ponctuation.There are several kinds of operators and punctuators. Les opérateurs sont utilisés dans les expressions pour décrire les opérations impliquant un ou plusieurs opérandes.Operators are used in expressions to describe operations involving one or more operands. Par exemple, l’expression a + b utilise l' + opérateur pour a ajouter les deux opérandes et b.For example, the expression a + b uses the + operator to add the two operands a and b. Les signes de ponctuation sont destinés au regroupement et à la séparation.Punctuators are for grouping and separating.

operator_or_punctuator
    : '{'  | '}'  | '['  | ']'  | '('   | ')'  | '.'  | ','  | ':'  | ';'
    | '+'  | '-'  | '*'  | '/'  | '%'   | '&'  | '|'  | '^'  | '!'  | '~'
    | '='  | '<'  | '>'  | '?'  | '??'  | '::' | '++' | '--' | '&&' | '||'
    | '->' | '==' | '!=' | '<=' | '>='  | '+=' | '-=' | '*=' | '/=' | '%='
    | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>'
    ;

right_shift
    : '>>'
    ;

right_shift_assignment
    : '>>='
    ;

La barre verticale dans les productions right_shift et right_shift_assignment est utilisée pour indiquer que, contrairement aux autres productions dans la syntaxe syntaxique, aucun caractère de tout type (pas même espace blanc) n’est autorisé entre les jetons.The vertical bar in the right_shift and right_shift_assignment productions are used to indicate that, unlike other productions in the syntactic grammar, no characters of any kind (not even whitespace) are allowed between the tokens. Ces productions sont traitées de façon spéciale pour permettre la gestion correcte des type_parameter_lists (paramètres de type).These productions are treated specially in order to enable the correct handling of type_parameter_lists (Type parameters).

Directives de prétraitementPre-processing directives

Les directives de prétraitement offrent la possibilité d’ignorer conditionnellement des sections de fichiers sources, de signaler des conditions d’erreur et d’avertissement, et de détourer des régions distinctes du code source.The pre-processing directives provide the ability to conditionally skip sections of source files, to report error and warning conditions, and to delineate distinct regions of source code. Le terme « directives de prétraitement » est utilisé uniquement à des fins de cohérence avec C++ les langages C et de programmation.The term "pre-processing directives" is used only for consistency with the C and C++ programming languages. Dans C#, il n’y a pas d’étape de pré-traitement distincte ; les directives de pré-traitement sont traitées dans le cadre de la phase d’analyse lexicale.In C#, there is no separate pre-processing step; pre-processing directives are processed as part of the lexical analysis phase.

pp_directive
    : pp_declaration
    | pp_conditional
    | pp_line
    | pp_diagnostic
    | pp_region
    | pp_pragma
    ;

Les directives de pré-traitement suivantes sont disponibles :The following pre-processing directives are available:

  • #defineet #undef, qui sont utilisés pour définir et annuler la définition, respectivement, des symboles de compilation conditionnelle (directives de déclaration).#define and #undef, which are used to define and undefine, respectively, conditional compilation symbols (Declaration directives).
  • #if, #elif, #else et#endif, qui sont utilisés pour ignorer de manière conditionnelle les sections du code source (directives de compilation conditionnelle).#if, #elif, #else, and #endif, which are used to conditionally skip sections of source code (Conditional compilation directives).
  • #line, qui est utilisé pour contrôler les numéros de ligne émis pour les erreurs et les avertissements (directives de ligne).#line, which is used to control line numbers emitted for errors and warnings (Line directives).
  • #erroret #warning, qui sont utilisés pour émettre des erreurs et des avertissements, respectivement (directives de diagnostic).#error and #warning, which are used to issue errors and warnings, respectively (Diagnostic directives).
  • #regionet #endregion, qui sont utilisés pour marquer explicitement les sections du code source (directives de région).#region and #endregion, which are used to explicitly mark sections of source code (Region directives).
  • #pragma, qui est utilisé pour spécifier des informations contextuelles facultatives pour le compilateur (directives pragma).#pragma, which is used to specify optional contextual information to the compiler (Pragma directives).

Une directive de prétraitement occupe toujours une ligne distincte de code source et commence toujours par un # caractère et un nom de directive de prétraitement.A pre-processing directive always occupies a separate line of source code and always begins with a # character and a pre-processing directive name. Un espace blanc peut se produire # avant le caractère et # entre le caractère et le nom de la directive.White space may occur before the # character and between the # character and the directive name.

Une ligne source contenant une #definedirective #undef, #if #elif #else ,,#endif ,#endregion ,, ou peut se terminer par un commentaire sur une seule ligne. #lineA source line containing a #define, #undef, #if, #elif, #else, #endif, #line, or #endregion directive may end with a single-line comment. Les commentaires délimités /* */ (style de commentaires) ne sont pas autorisés sur les lignes sources contenant des directives de prétraitement.Delimited comments (the /* */ style of comments) are not permitted on source lines containing pre-processing directives.

Les directives de pré-traitement ne sont pas des jetons et ne font pas partie de C#la syntaxe syntaxique de.Pre-processing directives are not tokens and are not part of the syntactic grammar of C#. Toutefois, les directives de prétraitement peuvent être utilisées pour inclure ou exclure des séquences de jetons et peuvent, de cette façon, affecter la C# signification d’un programme.However, pre-processing directives can be used to include or exclude sequences of tokens and can in that way affect the meaning of a C# program. Par exemple, une fois compilé, le programme :For example, when compiled, the program:

#define A
#undef B

class C
{
#if A
    void F() {}
#else
    void G() {}
#endif

#if B
    void H() {}
#else
    void I() {}
#endif
}

produit exactement la même séquence de jetons que le programme :results in the exact same sequence of tokens as the program:

class C
{
    void F() {}
    void I() {}
}

Par conséquent, contrairement à l’lexicale, les deux programmes sont très différents, syntaxiquement identiques.Thus, whereas lexically, the two programs are quite different, syntactically, they are identical.

Symboles de compilation conditionnelleConditional compilation symbols

La fonctionnalité de compilation conditionnelle fournie par #ifles #elifdirectives #else,, #endif et est contrôlée par le biais d’expressions de prétraitement (expressions de pré-traitement) et conditionnelle symboles de compilation.The conditional compilation functionality provided by the #if, #elif, #else, and #endif directives is controlled through pre-processing expressions (Pre-processing expressions) and conditional compilation symbols.

conditional_symbol
    : '<Any identifier_or_keyword except true or false>'
    ;

Un symbole de compilation conditionnelle a deux États possibles : défini ou non défini.A conditional compilation symbol has two possible states: defined or undefined. Au début du traitement lexical d’un fichier source, un symbole de compilation conditionnelle n’est pas défini, sauf s’il a été défini explicitement par un mécanisme externe (tel qu’une option de compilateur de ligne de commande).At the beginning of the lexical processing of a source file, a conditional compilation symbol is undefined unless it has been explicitly defined by an external mechanism (such as a command-line compiler option). Quand une #define directive est traitée, le symbole de compilation conditionnelle nommé dans cette directive devient défini dans ce fichier source.When a #define directive is processed, the conditional compilation symbol named in that directive becomes defined in that source file. Le symbole reste défini jusqu’à #undef ce qu’une directive pour ce même symbole soit traitée ou jusqu’à ce que la fin du fichier source soit atteinte.The symbol remains defined until an #undef directive for that same symbol is processed, or until the end of the source file is reached. L’une des conséquences est que #define les #undef directives et dans un fichier source n’ont aucun effet sur les autres fichiers sources du même programme.An implication of this is that #define and #undef directives in one source file have no effect on other source files in the same program.

Lorsqu’il est référencé dans une expression de pré-traitement, un symbole de compilation conditionnelle défini a truela valeur booléenne et un symbole de compilation conditionnelle non défini a la falsevaleur booléenne.When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false. Il n’est pas nécessaire que les symboles de compilation conditionnelle soient explicitement déclarés avant d’être référencés dans des expressions de prétraitement.There is no requirement that conditional compilation symbols be explicitly declared before they are referenced in pre-processing expressions. Au lieu de cela, les symboles non déclarés sont simplement non définis et falseont donc la valeur.Instead, undeclared symbols are simply undefined and thus have the value false.

L’espace de noms pour les symboles de compilation conditionnelle est distinct et distinct de toutes les autres C# entités nommées dans un programme.The name space for conditional compilation symbols is distinct and separate from all other named entities in a C# program. Les symboles de compilation conditionnelle peuvent uniquement être référencés #undef dans #define les directives et et dans les expressions de prétraitement.Conditional compilation symbols can only be referenced in #define and #undef directives and in pre-processing expressions.

Expressions de pré-traitementPre-processing expressions

Les expressions de prétraitement peuvent se #if produire #elif dans les directives et.Pre-processing expressions can occur in #if and #elif directives. Les opérateurs !, ==, != et||sont autorisés dans les expressions de prétraitement, et les parenthèses peuvent être utilisées pour le regroupement. &&The operators !, ==, !=, && and || are permitted in pre-processing expressions, and parentheses may be used for grouping.

pp_expression
    : whitespace? pp_or_expression whitespace?
    ;

pp_or_expression
    : pp_and_expression
    | pp_or_expression whitespace? '||' whitespace? pp_and_expression
    ;

pp_and_expression
    : pp_equality_expression
    | pp_and_expression whitespace? '&&' whitespace? pp_equality_expression
    ;

pp_equality_expression
    : pp_unary_expression
    | pp_equality_expression whitespace? '==' whitespace? pp_unary_expression
    | pp_equality_expression whitespace? '!=' whitespace? pp_unary_expression
    ;

pp_unary_expression
    : pp_primary_expression
    | '!' whitespace? pp_unary_expression
    ;

pp_primary_expression
    : 'true'
    | 'false'
    | conditional_symbol
    | '(' whitespace? pp_expression whitespace? ')'
    ;

Lorsqu’il est référencé dans une expression de pré-traitement, un symbole de compilation conditionnelle défini a truela valeur booléenne et un symbole de compilation conditionnelle non défini a la falsevaleur booléenne.When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false.

L’évaluation d’une expression de prétraitement génère toujours une valeur booléenne.Evaluation of a pre-processing expression always yields a boolean value. Les règles d’évaluation pour une expression de prétraitement sont les mêmes que celles d’une expression constante (expressions constantes), sauf que les seules entités définies par l’utilisateur qui peuvent être référencées sont des symboles de compilation conditionnelle.The rules of evaluation for a pre-processing expression are the same as those for a constant expression (Constant expressions), except that the only user-defined entities that can be referenced are conditional compilation symbols.

Directives de déclarationDeclaration directives

Les directives de déclaration sont utilisées pour définir ou annuler la définition des symboles de compilation conditionnelle.The declaration directives are used to define or undefine conditional compilation symbols.

pp_declaration
    : whitespace? '#' whitespace? 'define' whitespace conditional_symbol pp_new_line
    | whitespace? '#' whitespace? 'undef' whitespace conditional_symbol pp_new_line
    ;

pp_new_line
    : whitespace? single_line_comment? new_line
    ;

Le traitement d’une #define directive a pour effet de définir le symbole de compilation conditionnelle donné, en commençant par la ligne source qui suit la directive.The processing of a #define directive causes the given conditional compilation symbol to become defined, starting with the source line that follows the directive. De même, le traitement d' #undef une directive rend le symbole de compilation conditionnelle donné non défini, en commençant par la ligne source qui suit la directive.Likewise, the processing of an #undef directive causes the given conditional compilation symbol to become undefined, starting with the source line that follows the directive.

Les #define directives #undef et dans un fichier source doivent se trouver avant le premier jeton (jetons) dans le fichier source ; sinon, une erreur de compilation se produit.Any #define and #undef directives in a source file must occur before the first token (Tokens) in the source file; otherwise a compile-time error occurs. En termes intuitifs #define , #undef les directives et doivent précéder tout « code réel » dans le fichier source.In intuitive terms, #define and #undef directives must precede any "real code" in the source file.

L’exemple suivant :The example:

#define Enterprise

#if Professional || Enterprise
    #define Advanced
#endif

namespace Megacorp.Data
{
    #if Advanced
    class PivotTable {...}
    #endif
}

est valide, car #define les directives précèdent le premier namespace jeton (le mot clé) dans le fichier source.is valid because the #define directives precede the first token (the namespace keyword) in the source file.

L’exemple suivant génère une erreur au moment de la compilation, #define car un code réel suit :The following example results in a compile-time error because a #define follows real code:

#define A
namespace N
{
    #define B
    #if B
    class Class1 {}
    #endif
}

Un #define peut définir un symbole de compilation conditionnelle qui est déjà défini, sans qu’il n’y #undef ait d’intermédiaire pour ce symbole.A #define may define a conditional compilation symbol that is already defined, without there being any intervening #undef for that symbol. L’exemple ci-dessous définit un symbole A de compilation conditionnelle, puis le définit à nouveau.The example below defines a conditional compilation symbol A and then defines it again.

#define A
#define A

Un #undef peut « annuler la définition » d’un symbole de compilation conditionnelle qui n’est pas défini.A #undef may "undefine" a conditional compilation symbol that is not defined. L’exemple ci-dessous définit un symbole A de compilation conditionnelle, puis l’annule deux fois ; #undef bien que le second n’ait aucun effet, il est toujours valide.The example below defines a conditional compilation symbol A and then undefines it twice; although the second #undef has no effect, it is still valid.

#define A
#undef A
#undef A

Directives de compilation conditionnelleConditional compilation directives

Les directives de compilation conditionnelle permettent d’inclure ou d’exclure de manière conditionnelle des parties d’un fichier source.The conditional compilation directives are used to conditionally include or exclude portions of a source file.

pp_conditional
    : pp_if_section pp_elif_section* pp_else_section? pp_endif
    ;

pp_if_section
    : whitespace? '#' whitespace? 'if' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_elif_section
    : whitespace? '#' whitespace? 'elif' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_else_section:
    | whitespace? '#' whitespace? 'else' pp_new_line conditional_section?
    ;

pp_endif
    : whitespace? '#' whitespace? 'endif' pp_new_line
    ;

conditional_section
    : input_section
    | skipped_section
    ;

skipped_section
    : skipped_section_part+
    ;

skipped_section_part
    : skipped_characters? new_line
    | pp_directive
    ;

skipped_characters
    : whitespace? not_number_sign input_character*
    ;

not_number_sign
    : '<Any input_character except #>'
    ;

Comme indiqué par la syntaxe, les directives de compilation conditionnelle doivent être écrites sous la forme de jeux composés de #if , dans l’ordre, d’une directive, de #else zéro, d’une #endif ou de plusieurs #elif directives, de zéro ou d’une directive et d’une directive.As indicated by the syntax, conditional compilation directives must be written as sets consisting of, in order, an #if directive, zero or more #elif directives, zero or one #else directive, and an #endif directive. Les sections conditionnelles du code source sont placées entre les directives.Between the directives are conditional sections of source code. Chaque section est contrôlée par la directive qui précède immédiatement.Each section is controlled by the immediately preceding directive. Une section conditionnelle peut elle-même contenir des directives de compilation conditionnelle imbriquées, à condition que ces directives forment des jeux complets.A conditional section may itself contain nested conditional compilation directives provided these directives form complete sets.

Un pp_conditional sélectionne au plus l’un des conditional_sectioncontenus dans le traitement lexical normal :A pp_conditional selects at most one of the contained conditional_sections for normal lexical processing:

  • Les pp_expressions des directives #if et #elif sont évaluées dans l’ordre jusqu’à ce que l’un des deux produise true.The pp_expressions of the #if and #elif directives are evaluated in order until one yields true. Si une expression produit true, le conditional_section de la directive correspondante est sélectionné.If an expression yields true, the conditional_section of the corresponding directive is selected.
  • Si tous les pp_expressions génèrent false et si une directive #else est présente, le conditional_section de la directive #else est sélectionné.If all pp_expressions yield false, and if an #else directive is present, the conditional_section of the #else directive is selected.
  • Dans le cas contraire, aucun conditional_section n’est sélectionné.Otherwise, no conditional_section is selected.

Le conditional_sectionsélectionné, le cas échéant, est traité comme un input_sectionnormal : le code source contenu dans la section doit adhérer à la grammaire lexicale. les jetons sont générés à partir du code source dans la section. et les directives de pré-traitement dans la section ont les effets imposés.The selected conditional_section, if any, is processed as a normal input_section: the source code contained in the section must adhere to the lexical grammar; tokens are generated from the source code in the section; and pre-processing directives in the section have the prescribed effects.

Les conditional_sectionrestants, le cas échéant, sont traités comme des skipped_sections : à l’exception des directives de prétraitement, le code source de la section ne doit pas être conforme à la grammaire lexicale. aucun jeton n’est généré à partir du code source dans la section ; et les directives de prétraitement dans la section doivent être lexicalement correctes, mais elles ne sont pas traitées autrement.The remaining conditional_sections, if any, are processed as skipped_sections: except for pre-processing directives, the source code in the section need not adhere to the lexical grammar; no tokens are generated from the source code in the section; and pre-processing directives in the section must be lexically correct but are not otherwise processed. Au sein d’un conditional_section qui est traité comme un skipped_section, tous les conditional_sectionimbriqués (contenues dans les constructions #if... #endif et #region... #endregion) sont également traités comme skipped_ sections.Within a conditional_section that is being processed as a skipped_section, any nested conditional_sections (contained in nested #if...#endif and #region...#endregion constructs) are also processed as skipped_sections.

L’exemple suivant illustre la façon dont les directives de compilation conditionnelle peuvent imbriquer :The following example illustrates how conditional compilation directives can nest:

#define Debug       // Debugging on
#undef Trace        // Tracing off

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
            #if Trace
                WriteToLog(this.ToString());
            #endif
        #endif
        CommitHelper();
    }
}

À l’exception des directives de pré-traitement, le code source ignoré n’est pas soumis à l’analyse lexicale.Except for pre-processing directives, skipped source code is not subject to lexical analysis. Par exemple, le code suivant est valide malgré le Commentaire inachevé dans la #else section :For example, the following is valid despite the unterminated comment in the #else section:

#define Debug        // Debugging on

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
        #else
            /* Do something else
        #endif
    }
}

Notez, toutefois, que les directives de pré-traitement doivent être correctes lexicalement, même dans les sections ignorées du code source.Note, however, that pre-processing directives are required to be lexically correct even in skipped sections of source code.

Les directives de pré-traitement ne sont pas traitées quand elles apparaissent dans des éléments d’entrée multiligne.Pre-processing directives are not processed when they appear inside multi-line input elements. Par exemple, le programme :For example, the program:

class Hello
{
    static void Main() {
        System.Console.WriteLine(@"hello, 
#if Debug
        world
#else
        Nebraska
#endif
        ");
    }
}

génère la sortie :results in the output:

hello,
#if Debug
        world
#else
        Nebraska
#endif

Dans les cas particuliers, l’ensemble de directives de prétraitement qui est traité peut dépendre de l’évaluation de pp_expression.In peculiar cases, the set of pre-processing directives that is processed might depend on the evaluation of the pp_expression. L’exemple suivant :The example:

#if X
    /*
#else
    /* */ class Q { }
#endif

produit toujours le même flux de jetonsclass ( } Q { ), qu’il soit défini X ou non.always produces the same token stream (class Q { }), regardless of whether or not X is defined. Si X est défini, les seules directives traitées sont #if et #endif, en raison du commentaire sur plusieurs lignes.If X is defined, the only processed directives are #if and #endif, due to the multi-line comment. Si X n’est pas défini, alors trois directives (#if, #else, #endif) font partie de la directive définie.If X is undefined, then three directives (#if, #else, #endif) are part of the directive set.

Directives de diagnosticDiagnostic directives

Les directives de diagnostic sont utilisées pour générer explicitement des messages d’erreur et d’avertissement signalés de la même façon que d’autres erreurs et avertissements au moment de la compilation.The diagnostic directives are used to explicitly generate error and warning messages that are reported in the same way as other compile-time errors and warnings.

pp_diagnostic
    : whitespace? '#' whitespace? 'error' pp_message
    | whitespace? '#' whitespace? 'warning' pp_message
    ;

pp_message
    : new_line
    | whitespace input_character* new_line
    ;

L’exemple suivant :The example:

#warning Code review needed before check-in

#if Debug && Retail
    #error A build can't be both debug and retail
#endif

class Test {...}

génère toujours un avertissement (« révision du code nécessaire avant l’archivage ») et génère une erreur au moment de la compilation (« une build ne peut pas être à la fois Debug et Retail Retail ») si les symboles Debug conditionnels et sont tous deux définis.always produces a warning ("Code review needed before check-in"), and produces a compile-time error ("A build can't be both debug and retail") if the conditional symbols Debug and Retail are both defined. Notez qu’un pp_message peut contenir du texte arbitraire. plus précisément, il n’a pas besoin de contenir des jetons correctement formés, comme indiqué par le guillemet simple dans le mot can't.Note that a pp_message can contain arbitrary text; specifically, it need not contain well-formed tokens, as shown by the single quote in the word can't.

Directives de régionRegion directives

Les directives de région sont utilisées pour marquer explicitement les zones de code source.The region directives are used to explicitly mark regions of source code.

pp_region
    : pp_start_region conditional_section? pp_end_region
    ;

pp_start_region
    : whitespace? '#' whitespace? 'region' pp_message
    ;

pp_end_region
    : whitespace? '#' whitespace? 'endregion' pp_message
    ;

Aucune signification sémantique n’est attachée à une région ; les régions sont destinées à être utilisées par le programmeur ou par des outils automatisés pour marquer une section du code source.No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. Le message spécifié dans une #region directive #endregion ou n’a pas la même signification sémantique ; il sert simplement à identifier la région.The message specified in a #region or #endregion directive likewise has no semantic meaning; it merely serves to identify the region. Les directives #region et #endregion correspondantes peuvent avoir différents pp_messages.Matching #region and #endregion directives may have different pp_messages.

Traitement lexical d’une région :The lexical processing of a region:

#region
...
#endregion

correspond exactement au traitement lexical d’une directive de compilation conditionnelle au format suivant :corresponds exactly to the lexical processing of a conditional compilation directive of the form:

#if true
...
#endif

Directives de ligneLine directives

Les directives de ligne peuvent être utilisées pour modifier les numéros de ligne et les noms de fichiers sources qui sont signalés par le compilateur dans la sortie, tels que les avertissements et les erreurs, et qui sont utilisés par les attributs d’informations de l’appelant (attributs des informationsde l’appelant).Line directives may be used to alter the line numbers and source file names that are reported by the compiler in output such as warnings and errors, and that are used by caller info attributes (Caller info attributes).

Les directives de ligne sont le plus souvent utilisées dans les outils de C# méta-programmation qui génèrent du code source à partir d’autres entrées de texte.Line directives are most commonly used in meta-programming tools that generate C# source code from some other text input.

pp_line
    : whitespace? '#' whitespace? 'line' whitespace line_indicator pp_new_line
    ;

line_indicator
    : decimal_digit+ whitespace file_name
    | decimal_digit+
    | 'default'
    | 'hidden'
    ;

file_name
    : '"' file_name_character+ '"'
    ;

file_name_character
    : '<Any input_character except ">'
    ;

Quand aucune #line directive n’est présente, le compilateur signale les véritables numéros de ligne et les noms de fichiers sources dans sa sortie.When no #line directives are present, the compiler reports true line numbers and source file names in its output. Lors du traitement d’une directive #line qui comprend un line_indicator qui n’est pas default, le compilateur traite la ligne après la directive comme ayant le numéro de ligne donné (et le nom de fichier, si spécifié).When processing a #line directive that includes a line_indicator that is not default, the compiler treats the line after the directive as having the given line number (and file name, if specified).

Une #line default directive inverse l’effet de toutes les directives de #line précédentes.A #line default directive reverses the effect of all preceding #line directives. Le compilateur signale des informations de ligne vraies pour les lignes suivantes, #line exactement comme si aucune directive n’avait été traitée.The compiler reports true line information for subsequent lines, precisely as if no #line directives had been processed.

Une #line hidden directive n’a aucun effet sur le fichier et les numéros de ligne signalés dans les messages d’erreur, mais affecte le débogage au niveau de la source.A #line hidden directive has no effect on the file and line numbers reported in error messages, but does affect source level debugging. Lors du débogage, toutes les lignes entre #line hidden une directive et la #line directive suivante (qui n' #line hiddenest pas) n’ont pas d’informations sur le numéro de ligne.When debugging, all lines between a #line hidden directive and the subsequent #line directive (that is not #line hidden) have no line number information. Quand vous exécutez le code pas à pas dans le débogueur, ces lignes sont entièrement ignorées.When stepping through code in the debugger, these lines will be skipped entirely.

Notez qu’un nom_fichier diffère d’un littéral de chaîne standard en ce que les caractères d’échappement ne sont pas traités ; le caractère « \ » désigne simplement un caractère barre oblique inverse ordinaire dans un nom_fichier.Note that a file_name differs from a regular string literal in that escape characters are not processed; the "\" character simply designates an ordinary backslash character within a file_name.

Directives pragmaPragma directives

La #pragma directive de prétraitement est utilisée pour spécifier des informations contextuelles facultatives pour le compilateur.The #pragma preprocessing directive is used to specify optional contextual information to the compiler. Les informations fournies dans une #pragma directive ne modifient jamais la sémantique du programme.The information supplied in a #pragma directive will never change program semantics.

pp_pragma
    : whitespace? '#' whitespace? 'pragma' whitespace pragma_body pp_new_line
    ;

pragma_body
    : pragma_warning_body
    ;

C#fournit #pragma des directives pour contrôler les avertissements du compilateur.C# provides #pragma directives to control compiler warnings. Les futures versions du langage peuvent inclure des #pragma directives supplémentaires.Future versions of the language may include additional #pragma directives. Pour garantir l’interopérabilité avec C# d’autres compilateurs, le C# compilateur Microsoft n’émet pas d’erreurs de #pragma compilation pour les directives inconnues ; ces directives génèrent toutefois des avertissements.To ensure interoperability with other C# compilers, the Microsoft C# compiler does not issue compilation errors for unknown #pragma directives; such directives do however generate warnings.

pragma warningPragma warning

La #pragma warning directive est utilisée pour désactiver ou restaurer tout ou un ensemble particulier de messages d’avertissement lors de la compilation du texte de programme suivant.The #pragma warning directive is used to disable or restore all or a particular set of warning messages during compilation of the subsequent program text.

pragma_warning_body
    : 'warning' whitespace warning_action
    | 'warning' whitespace warning_action whitespace warning_list
    ;

warning_action
    : 'disable'
    | 'restore'
    ;

warning_list
    : decimal_digit+ (whitespace? ',' whitespace? decimal_digit+)*
    ;

Une #pragma warning directive qui omet la liste d’avertissements affecte tous les avertissements.A #pragma warning directive that omits the warning list affects all warnings. Une #pragma warning directive qui comprend une liste d’avertissements affecte uniquement les avertissements qui sont spécifiés dans la liste.A #pragma warning directive that includes a warning list affects only those warnings that are specified in the list.

Une #pragma warning disable directive désactive tout ou l’ensemble d’avertissements donné.A #pragma warning disable directive disables all or the given set of warnings.

Une #pragma warning restore directive restaure tout ou partie des avertissements donnés à l’État qui était en vigueur au début de l’unité de compilation.A #pragma warning restore directive restores all or the given set of warnings to the state that was in effect at the beginning of the compilation unit. Notez que si un avertissement particulier a été désactivé en externe, #pragma warning restore a (que ce soit pour tous ou l’avertissement spécifique) ne réactivera pas cet avertissement.Note that if a particular warning was disabled externally, a #pragma warning restore (whether for all or the specific warning) will not re-enable that warning.

L’exemple suivant illustre l’utilisation #pragma warning de pour désactiver temporairement l’avertissement signalé lorsque des membres obsolètes sont référencés, à l’aide du numéro C# d’avertissement du compilateur Microsoft.The following example shows use of #pragma warning to temporarily disable the warning reported when obsoleted members are referenced, using the warning number from the Microsoft C# compiler.

using System;

class Program
{
    [Obsolete]
    static void Foo() {}

    static void Main() {
#pragma warning disable 612
    Foo();
#pragma warning restore 612
    }
}