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:
- 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.
- 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.
- 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\u
caractères « »\U
ou « ».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\u0061ss
les mots clés, le jeton « » est un identificateur et est le@class
mê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é, lesget
identificateurs «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 int
valeurs uint
de long
types, 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
êtreuint
repré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 ouu
, il a le premier de ces types dans lequel sa valeur peutuint
êtreulong
représentée :,.If the literal is suffixed byU
oru
, 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 oul
, il a le premier de ces types dans lequel sa valeur peutlong
êtreulong
représentée :,.If the literal is suffixed byL
orl
, it has the first of these types in which its value can be represented:long
,ulong
. - Si le littéral est précédé
UL
d’un suffixe,ul
Ul
,LU
uL
,Lu
,lU
,,lu
ou, il est deulong
type.If the literal is suffixed byUL
,Ul
,uL
,ul
,LU
,Lu
,lU
, orlu
, it is of typeulong
.
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 long
litté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 typeint
with the value -2147483648 (-2^31). Dans toutes les autres situations, une telle decimal_integer_literal est de typeuint
.In all other situations, such a decimal_integer_literal is of typeuint
. - Lorsqu’un decimal_integer_literal avec la valeur 9223372036854775808 (2 ^ 63) et aucun integer_type_suffix ou integer_type_suffix
L
oul
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 typelong
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_suffixL
orl
appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of typelong
with the value -9223372036854775808 (-2^63). Dans toutes les autres situations, une telle decimal_integer_literal est de typeulong
.In all other situations, such a decimal_integer_literal is of typeulong
.
Littéraux réelsReal literals
Les littéraux réels sont utilisés pour écrire des valeurs float
de double
types, decimal
et.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
estf
ou est defloat
type.A real literal suffixed byF
orf
is of typefloat
. Par exemple, les littéraux1f
,1.5f
,1e10f
et123.456F
sont tous de typefloat
.For example, the literals1f
,1.5f
,1e10f
, and123.456F
are all of typefloat
. - Littéral réel dont le suffixe
D
estd
ou est dedouble
type.A real literal suffixed byD
ord
is of typedouble
. Par exemple, les littéraux1d
,1.5d
,1e10d
et123.456D
sont tous de typedouble
.For example, the literals1d
,1.5d
,1e10d
, and123.456D
are all of typedouble
. - Littéral réel dont le suffixe
M
estm
ou est dedecimal
type.A real literal suffixed byM
orm
is of typedecimal
. Par exemple, les littéraux1m
,1.5m
,1e10m
et123.456M
sont tous de typedecimal
.For example, the literals1m
,1.5m
,1e10m
, and123.456M
are all of typedecimal
. Ce littéral est converti en unedecimal
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 adecimal
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, le2.900m
littéral sera analysé pour former la décimale avec le0
signe, le2900
coefficient et3
l’échelle.Hence, the literal2.900m
will be parsed to form the decimal with sign0
, coefficient2900
, and scale3
.
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\x
suivant «».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:
#define
et#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).#error
et#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).#region
et#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 #define
directive #undef
, #if
#elif
#else
,,#endif
,#endregion
,, ou peut se terminer par un commentaire sur une seule ligne. #line
A 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 #if
les #elif
directives #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 true
la valeur booléenne et un symbole de compilation conditionnelle non défini a la false
valeur 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 false
ont 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 true
la valeur booléenne et un symbole de compilation conditionnelle non défini a la false
valeur 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 produisetrue
.The pp_expressions of the#if
and#elif
directives are evaluated in order until one yieldstrue
. Si une expression produittrue
, le conditional_section de la directive correspondante est sélectionné.If an expression yieldstrue
, 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 yieldfalse
, 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 hidden
est 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
}
}
Commentaires
Chargement du commentaire...