字句構造Lexical structure

プログラムPrograms

C# プログラム _ は、1つまたは複数の _ソースファイル_ で構成され、正式には _ コンパイル単位 (コンパイル単位) として知られています。A C# program _ consists of one or more _source files_, known formally as _ compilation units (Compilation units). ソースファイルは、順序付けられた Unicode 文字のシーケンスです。A source file is an ordered sequence of Unicode characters. ソースファイルは、通常、ファイルシステム内のファイルと1対1で対応していますが、この対応は必要ありません。Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. 移植性を最大にするために、ファイルシステム内のファイルを UTF-8 エンコードでエンコードすることをお勧めします。For maximal portability, it is recommended that files in a file system be encoded with the UTF-8 encoding.

概念的に言えば、プログラムは次の3つの手順を使用してコンパイルされます。Conceptually speaking, a program is compiled using three steps:

  1. 変換。特定の文字レパートリーとエンコードスキームのファイルを Unicode 文字のシーケンスに変換します。Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters.
  2. 字句分析。 Unicode 入力文字のストリームをトークンのストリームに変換します。Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens.
  3. 構文分析。トークンのストリームを実行可能コードに変換します。Syntactic analysis, which translates the stream of tokens into executable code.

文法Grammars

この仕様には、2つの文法を使用した C# プログラミング言語の構文が示されています。This specification presents the syntax of the C# programming language using two grammars. *字句文法 _ (字句文法) では、Unicode 文字を組み合わせることによって、行ターミネータ、空白、コメント、トークン、およびプリプロセスディレクティブを形成する方法を定義します。The *lexical grammar _ (Lexical grammar) defines how Unicode characters are combined to form line terminators, white space, comments, tokens, and pre-processing directives. _ 構文 文法 * (構文文法) は、字句文法の結果として生成されるトークンを結合して C# プログラムを形成する方法を定義します。The _ syntactic grammar* (Syntactic grammar) defines how the tokens resulting from the lexical grammar are combined to form C# programs.

文法の表記Grammar notation

字句文法と構文文法は、ANTLR 文法ツールの表記法を使用して Backus-Naur フォームに表示されます。The lexical and syntactic grammars are presented in Backus-Naur form using the notation of the ANTLR grammar tool.

字句文法Lexical grammar

C# の字句文法は、 字句解析トークン、および プリプロセスディレクティブで示されています。The lexical grammar of C# is presented in Lexical analysis, Tokens, and Pre-processing directives. 字句文法のターミナルシンボルは Unicode 文字セットの文字であり、字句文法は、文字を結合してトークン (トークン)、空白 (空白)、コメント (コメント)、プリプロセスディレクティブ (プリプロセスディレクティブ) を形成する方法を指定します。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).

C# プログラム内のすべてのソースファイルは、字句文法 (字句解析) の 入力 の実稼働に準拠している必要があります。Every source file in a C# program must conform to the input production of the lexical grammar (Lexical analysis).

構文の文法Syntactic grammar

C# の構文文法は、この章の後の章と付録に記載されています。The syntactic grammar of C# is presented in the chapters and appendices that follow this chapter. 構文文法のターミナルシンボルは、字句文法によって定義されたトークンです。構文文法では、トークンを結合して C# プログラムを形成する方法を指定します。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.

C# プログラム内のすべてのソースファイルは、構文文法 (コンパイル単位) の compilation_unit 運用環境に準拠している必要があります。Every source file in a C# program must conform to the compilation_unit production of the syntactic grammar (Compilation units).

字句解析Lexical analysis

入力 の運用では、C# ソースファイルの構文構造を定義します。The input production defines the lexical structure of a C# source file. C# プログラム内の各ソースファイルは、この字句文法の実稼働に準拠している必要があります。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
    ;

C# ソースファイルの構文構造は、行ターミネータ (行ターミネータ)、空白 (空白)、コメント (コメント)、トークン (トークン)、プリプロセスディレクティブ (プリプロセスディレクティブ) の5つの基本要素によって構成されます。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). これらの基本的な要素のうち、C# プログラム (構文文法) の構文文法ではトークンのみが重要です。Of these basic elements, only tokens are significant in the syntactic grammar of a C# program (Syntactic grammar).

C# ソースファイルの字句処理では、ファイルを一連のトークンに減らすことで、構文分析への入力となります。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. 行ターミネータ、空白、コメントはトークンを区切るために使用でき、プリプロセスディレクティブによってソースファイルのセクションがスキップされることがありますが、それ以外の場合、これらの字句要素は C# プログラムの構文構造には影響しません。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.

挿入文字列リテラル (補間文字列リテラル) の場合、1つのトークンは字句解析によって最初に生成されますが、複数の入力要素に分割されます。これは、すべての補間文字列リテラルが解決されるまで、字句解析に繰り返し適用されます。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. その後、結果として得られるトークンは、構文分析の入力として機能します。The resulting tokens then serve as input to the syntactic analysis.

複数の字句文法の発行がソースファイル内の文字のシーケンスと一致する場合、構文処理では常に、可能な限り長い字句要素が形成されます。When several lexical grammar productions match a sequence of characters in a source file, the lexical processing always forms the longest possible lexical element. たとえば、文字シーケンスは単 // 一行コメントの先頭として処理されます。これは、その字句要素が1つのトークンより長いためです /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.

ラインターミネータLine terminators

行ターミネータは、C# ソースファイルの文字を行に分割します。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)>'
    ;

ファイルの終端マーカーを追加するソースコード編集ツールとの互換性を確保し、適切に終了した行のシーケンスとしてソースファイルを表示できるようにするには、C# プログラムのすべてのソースファイルに次の変換を順番に適用します。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:

  • ソースファイルの最後の文字がコントロール Z 文字 () の場合 U+001A 、この文字は削除されます。If the last character of the source file is a Control-Z character (U+001A), this character is deleted.
  • ソースファイルが空では U+000D なく、ソースファイルの最後の文字が復帰 ( U+000D )、改行 ( U+000A )、行区切り記号 ()、 U+2028 または段落区切り記号 () ではない場合、ソースファイルの末尾に復帰文字 () が追加され 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).

コメントComments

単一行コメントと区切られたコメントという 2 つの形式のコメントがサポートされています。Two forms of comments are supported: single-line comments and delimited comments.\ 単一行コメント _ は、文字で始まり、 // ソース行の末尾まで拡張されます。\ Single-line comments _ start with the characters // and extend to the end of the source line. *区切ら* れたコメントは、文字で始まり、 /_ 文字で終わり */ ます。_Delimited comments_ start with the characters /_ and end with the characters */. 区切られたコメントは、複数行にまたがる場合があります。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 *>'
    ;

コメントは入れ子になりません。Comments do not nest. 文字シーケンスとは、 /* */ コメント内では特別な意味を持ちません。また、 // 文字シーケンスとは、区切られた // /* コメント内で特別な意味を持ちません。The character sequences /* and */ have no special meaning within a // comment, and the character sequences // and /* have no special meaning within a delimited comment.

コメントは、文字リテラルと文字列リテラル内では処理されません。Comments are not processed within character and string literals.

例を示します。The example

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

これには区切られたコメントが含まれています。includes a delimited comment.

例を示します。The 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");
    }
}

複数の単一行コメントが示されています。shows several single-line comments.

空白White space

空白は、Unicode クラス Zs (空白文字を含む) と、水平タブ文字、垂直タブ文字、およびフォームフィード文字を含む任意の文字として定義されます。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)>'
    ;

トークンTokens

トークンには、識別子、キーワード、リテラル、演算子、および区切り記号のいくつかの種類があります。There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators. 空白とコメントはトークンではありませんが、トークンの区切り記号として機能します。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
    ;

Unicode 文字エスケープシーケンスUnicode character escape sequences

Unicode 文字のエスケープシーケンスは、Unicode 文字を表します。A Unicode character escape sequence represents a Unicode character. Unicode 文字のエスケープシーケンスは、識別子 (識別子)、文字リテラル (文字リテラル)、および通常の文字列リテラル (文字列リテラル) で処理されます。Unicode character escape sequences are processed in identifiers (Identifiers), character literals (Character literals), and regular string literals (String literals). Unicode 文字のエスケープは、他の場所では処理されません (たとえば、operator、など、または keyword を形成する場合)。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
    ;

Unicode エスケープシーケンスは、" \u " または "" 文字の後に続く16進数で形成される1つの unicode 文字を表し \U ます。A Unicode escape sequence represents the single Unicode character formed by the hexadecimal number following the "\u" or "\U" characters. C# では、文字と文字列値の Unicode コードポイントの16ビットエンコードが使用されるため、U + 10000 から U + 10FFFF の範囲の Unicode 文字は、文字リテラルでは許可されません。また、文字列リテラルでは Unicode サロゲートペアを使用して表されます。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. 0x10FFFF を超えるコードポイントを含む Unicode 文字はサポートされていません。Unicode characters with code points above 0x10FFFF are not supported.

複数の翻訳は実行されません。Multiple translations are not performed. たとえば、文字列リテラル "" は、"" \u005Cu005C \u005C ではなく "" に相当し \ ます。For instance, the string literal "\u005Cu005C" is equivalent to "\u005C" rather than "\". Unicode 値 \u005C は文字 " \ " です。The Unicode value \u005C is the character "\".

例を示します。The example

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

のいくつかの使用方法 \u0066 を示します。これは、文字 "" のエスケープシーケンスです fshows several uses of \u0066, which is the escape sequence for the letter "f". プログラムはに相当します。The program is equivalent to

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

識別子Identifiers

このセクションで示す識別子の規則は、Unicode 標準の使用方法31で推奨されているものと正確に対応しています。ただし、アンダースコアは (C プログラミング言語では従来のように) 最初の文字として許可されており、識別子として @ キーワードを使用できるようにするためにプレフィックスとして使用できます。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>'
    ;

上記の Unicode 文字クラスの詳細については、Unicode Standard バージョン3.0 のセクション4.5 を参照してください。For information on the Unicode character classes mentioned above, see The Unicode Standard, Version 3.0, section 4.5.

有効な識別子の例 identifier1 としては、""、""、"" などがあり _identifier2 @if ます。Examples of valid identifiers include "identifier1", "_identifier2", and "@if".

準拠するプログラムの識別子は、unicode 規格の使用方法15で定義されているように、Unicode 正規形 C で定義されている正規の形式である必要があります。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. 正規形 C ではない識別子に遭遇した場合の動作は、実装によって定義されます。ただし、診断は必要ありません。The behavior when encountering an identifier not in Normalization Form C is implementation-defined; however, a diagnostic is not required.

プレフィックス "" を使用すると、 @ キーワードを識別子として使用できるようになります。これは、他のプログラミング言語とのやり取りに役立ちます。The prefix "@" enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. この文字 @ は実際には識別子の一部ではないため、識別子は、プレフィックスなしで通常の識別子として他の言語で認識される可能性があります。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. プレフィックスを持つ識別子 @ は、逐語的 識別子 と呼ばれます。An identifier with an @ prefix is called a verbatim identifier. @キーワードではない識別子に対してプレフィックスを使用することは許可されますが、スタイルの問題としては使用しないことを強くお勧めします。Use of the @ prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style.

この例では、次の処理を実行します。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);
    }
}

"" という名前のパラメーターを受け取る "" という名前の静的メソッドを使用して、"" という名前のクラスを定義 class static bool します。defines a class named "class" with a static method named "static" that takes a parameter named "bool". キーワードでは Unicode エスケープは許可されていないため、トークン " cl\u0061ss " は識別子であり、"" と同じ識別子です @classNote that since Unicode escapes are not permitted in keywords, the token "cl\u0061ss" is an identifier, and is the same identifier as "@class".

2つの識別子は、次の変換が適用された後に同一である場合は同じと見なされます。Two identifiers are considered the same if they are identical after the following transformations are applied, in order:

  • プレフィックス " @ " (使用されている場合) は削除されます。The prefix "@", if used, is removed.
  • unicode_escape_sequence は、対応する unicode 文字に変換されます。Each unicode_escape_sequence is transformed into its corresponding Unicode character.
  • すべての formatting_character が削除されます。Any formatting_character s are removed.

2つの連続するアンダースコア文字 () を含む識別子 U+005F は、実装で使用するために予約されています。Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation. たとえば、実装では、2つのアンダースコアで始まる拡張キーワードを使用できます。For example, an implementation might provide extended keywords that begin with two underscores.

キーワードKeywords

キーワード は、予約されている識別子に似た文字シーケンスであり、文字で始まる場合を除き、識別子として使用することはできません @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'
    ;

文法の一部では、特定の識別子は特別な意味を持ちますが、キーワードではありません。In some places in the grammar, specific identifiers have special meaning, but are not keywords. このような識別子は、"コンテキストキーワード" と呼ばれることもあります。Such identifiers are sometimes referred to as "contextual keywords". たとえば、プロパティ宣言内では、" get " 識別子と " set " 識別子には特別な意味があります (アクセサー)。For example, within a property declaration, the "get" and "set" identifiers have special meaning (Accessors). または以外の get 識別子 set は、これらの場所では許可されないため、この使用は、これらの単語を識別子として使用する場合と競合しません。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. 他のケースでは、暗黙的に型指定された var ローカル変数宣言 (ローカル変数宣言) で識別子 "" が使用されているなどの場合、コンテキストキーワードは宣言された名前と競合する可能性があります。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. このような場合、宣言された名前は、コンテキストキーワードとして識別子を使用するよりも優先されます。In such cases, the declared name takes precedence over the use of the identifier as a contextual keyword.

リテラルLiterals

"リテラル" は、値のソース コード表現です。A literal is a source code representation of a value.

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

ブール型リテラルBoolean literals

ブール型リテラル値には、との2つがあり true false ます。There are two boolean literal values: true and false.

boolean_literal
    : 'true'
    | 'false'
    ;

Boolean_literal の型が bool です。The type of a boolean_literal is bool.

整数リテラルInteger literals

整数リテラルは、、、および型の値を書き込むために使用され int uint long ulong ます。Integer literals are used to write values of types int, uint, long, and ulong. 整数リテラルには、10進数と16進数という2つの形式があります。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';

整数リテラルの型は、次のように決定されます。The type of an integer literal is determined as follows:

  • リテラルにサフィックスがない場合は int 、、、 uint long 、の各型の値を表すことができ ulong ます。If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
  • リテラルのサフィックスがまたはの場合は、 U u 、、の各型の値を表すことができます uint ulongIf the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.
  • リテラルのサフィックスがまたはの場合は、 L l 、、の各型の値を表すことができます long ulongIf the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong.
  • リテラルのサフィックスが、、、、、、、 UL Ul uL ul LU Lu lU 、または lu の場合、型は ulong です。If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.

整数リテラルによって表される値が型の範囲外にある場合は ulong 、コンパイル時エラーが発生します。If the value represented by an integer literal is outside the range of the ulong type, a compile-time error occurs.

スタイルの場合は、"" の代わりに "" を使用して型のリテラルを作成することをお勧めし L l long ます。これは、文字 " l " を数字 "" と混同しやすいためです 1As 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".

最小 int 値と最小 long 値を10進整数リテラルとして記述できるようにするには、次の2つの規則を使用します。To permit the smallest possible int and long values to be written as decimal integer literals, the following two rules exist:

  • 値が 2147483648 (2 ^ 31) の decimal_integer_literal が、単項マイナス演算子トークン (単項マイナス演算子) の直後にトークンとして表示され integer_type_suffix ない場合、結果は int -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). その他のすべての状況では、このような decimal_integer_literal は型に uint なります。In all other situations, such a decimal_integer_literal is of type uint.
  • 値が 9223372036854775808 (2 ^ 63) で、 integer_type_suffix または integer_type_suffix がない decimal_integer_literalL または l 単項マイナス演算子トークンの直後にトークンとして表示される場合 (単項マイナス演算子)、結果は long -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). その他のすべての状況では、このような decimal_integer_literal は型に ulong なります。In all other situations, such a decimal_integer_literal is of type ulong.

実数リテラルReal literals

実数リテラルは、、、および型の値を書き込むために使用され float double decimal ます。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'
    ;

Real_type_suffix が指定されていない場合、実際のリテラルの型はに double なります。If no real_type_suffix is specified, the type of the real literal is double. それ以外の場合は、実際の型サフィックスによって、次のように実際のリテラルの型が決定されます。Otherwise, the real type suffix determines the type of the real literal, as follows:

  • またはのサフィックスが付いた実数リテラル F f は型 float です。A real literal suffixed by F or f is of type float. たとえば、リテラル、、 1f 1.5f 1e10f123.456F はすべて型 float です。For example, the literals 1f, 1.5f, 1e10f, and 123.456F are all of type float.
  • またはのサフィックスが付いた実数リテラル D d は型 double です。A real literal suffixed by D or d is of type double. たとえば、リテラル、、 1d 1.5d 1e10d123.456D はすべて型 double です。For example, the literals 1d, 1.5d, 1e10d, and 123.456D are all of type double.
  • またはのサフィックスが付いた実数リテラル M m は型 decimal です。A real literal suffixed by M or m is of type decimal. たとえば、リテラル、、 1m 1.5m 1e10m123.456M はすべて型 decimal です。For example, the literals 1m, 1.5m, 1e10m, and 123.456M are all of type decimal. このリテラルは、 decimal 正確な値を取得することによって値に変換され、必要に応じて、銀行型丸め (10 進数型) を使用して最も近い表現可能な値に丸められます。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). リテラル内のすべての小数点以下桁数は、値が丸められた場合、または値がゼロの場合 (後者の場合は符号と小数点以下桁数が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). このため、リテラルは、 2.900m 符号 0 、係数、および小数点以下桁数の10進数を形成するために解析され 2900 3 ます。Hence, the literal 2.900m will be parsed to form the decimal with sign 0, coefficient 2900, and scale 3.

指定されたリテラルを指定された型で表すことができない場合、コンパイル時エラーが発生します。If the specified literal cannot be represented in the indicated type, a compile-time error occurs.

型または型の実数リテラルの floatdouble は、IEEE の "近似値に丸める" モードを使用して決定されます。The value of a real literal of type float or double is determined by using the IEEE "round to nearest" mode.

実際のリテラルでは、小数点の後には常に10進数が必要であることに注意してください。Note that in a real literal, decimal digits are always required after the decimal point. たとえば、は実際のリテラルですが、で 1.3F 1.F はありません。For example, 1.3F is a real literal but 1.F is not.

文字リテラルCharacter literals

文字リテラルは1つの文字を表し、通常はのように引用符で囲まれた文字で構成さ 'a' れます。A character literal represents a single character, and usually consists of a character in quotes, as in 'a'.

注: ANTLR 文法表記法を使用すると、次のように混乱が生じます。Note: The ANTLR grammar notation makes the following confusing! ANTLR では、これを記述すると、 \' 1 つの引用符が使用さ ' れます。In ANTLR, when you write \' it stands for a single quote '. また、記述する場合 \\ は、1つの円記号を表し \ ます。And when you write \\ it stands for a single backslash \. したがって、文字リテラルの最初の規則は、1つの引用符、1文字、1つの引用符で始まることを意味します。Therefore the first rule for a character literal means it starts with a single quote, then a character, then a single quote. また、11つの単純なエスケープシーケンスは、、、、、、、、、、 \' \" \\ \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?;

文字内の円記号 () の後に続く文字は、、、、、、、、、、、、、、 \ のいずれかである必要があり ' " \ 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. それ以外の場合は、コンパイル時のエラーが発生します。Otherwise, a compile-time error occurs.

16進数のエスケープシーケンスは、1つの Unicode 文字を表し、値は "" の後に16進数で形成され \x ます。A hexadecimal escape sequence represents a single Unicode character, with the value formed by the hexadecimal number following "\x".

文字リテラルによって表される値がより大きい場合 U+FFFF 、コンパイル時エラーが発生します。If the value represented by a character literal is greater than U+FFFF, a compile-time error occurs.

文字リテラル内の Unicode 文字エスケープシーケンス (unicode 文字エスケープシーケンス) は、の範囲内である必要があり U+0000 U+FFFF ます。A Unicode character escape sequence (Unicode character escape sequences) in a character literal must be in the range U+0000 to U+FFFF.

単純なエスケープシーケンスは、次の表に示すように、Unicode 文字エンコーディングを表します。A simple escape sequence represents a Unicode character encoding, as described in the table below.

エスケープ シーケンスEscape sequence 文字名Character name Unicode エンコーディングUnicode encoding
\' 単一引用符Single quote 0x0027
\" 二重引用符Double quote 0x0022
\\ 円記号Backslash 0x005C
\0 [Null]Null 0x0000
\a アラート:Alert 0x0007
\b バックスペースBackspace 0x0008
\f フォーム フィードForm feed 0x000C
\n 改行New line 0x000A
\r キャリッジ リターンCarriage return 0x000D
\t 水平タブHorizontal tab 0x0009
\v 垂直タブVertical tab 0x000B

Character_literal の型が char です。The type of a character_literal is char.

文字列リテラルString literals

C# では、2つの形式の文字列リテラルをサポートしています。 *通常の文字列リテラル _ と _ 逐語的文字列リテラル *。C# supports two forms of string literals: regular string literals _ and _verbatim string literals**.

通常の文字列リテラルは、のように、二重引用符で囲まれた0個以上の文字で構成さ "hello" れます。また、単純なエスケープシーケンス ( \t タブ文字のなど) と16進数および 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.

逐語的文字列リテラルは、 @ 文字の後に二重引用符文字、0個以上の文字、および終わりの二重引用符文字で構成されます。A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. 簡単な例を次に示し @"hello" ます。A simple example is @"hello". 逐語的文字列リテラルでは、区切り記号の間の文字は逐語的に解釈されます。唯一の例外は quote_escape_sequence です。In a verbatim string literal, the characters between the delimiters are interpreted verbatim, the only exception being a quote_escape_sequence. 特に、単純なエスケープシーケンス、および16進数および Unicode のエスケープシーケンスは、逐語的文字列リテラルでは処理されません。In particular, simple escape sequences, and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. 逐語的文字列リテラルは複数の行にまたがる場合があります。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
    : '""'
    ;

Regular_string_literal_character 内の円記号 () の後に続く文字は、、、、、、、、、、、、、、 \ のいずれかである必要があり ' " \ 0 a b f n r t u U x v ます。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. それ以外の場合は、コンパイル時のエラーが発生します。Otherwise, a compile-time error occurs.

例を示します。The 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";

さまざまな文字列リテラルを示します。shows a variety of string literals. 最後の文字列リテラルは、 j 複数の行にまたがる逐語的文字列リテラルです。The last string literal, j, is a verbatim string literal that spans multiple lines. 引用符の間の文字 (改行文字などの空白文字を含む) は、そのまま保持されます。The characters between the quotation marks, including white space such as new line characters, are preserved verbatim.

16進数のエスケープシーケンスは数値の16進数を持つことができるため、文字列リテラルには "\x123" 16 進値123の1文字が含まれます。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. 16進数値12の後に3文字目が続く文字を含む文字列を作成するに "\x00123" は、または代わりにを記述 "\x12" + "3" します。To create a string containing the character with hex value 12 followed by the character 3, one could write "\x00123" or "\x12" + "3" instead.

String_literal の型が string です。The type of a string_literal is string.

各文字列リテラルは、必ずしも新しい文字列インスタンスになるとは限りません。Each string literal does not necessarily result in a new string instance. 文字列等値演算子 (文字列等値演算子) によって等価である2つ以上の文字列リテラルが同じプログラムに出現する場合、これらの文字列リテラルは同じ文字列インスタンスを参照します。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. たとえば、によって生成される出力は、For instance, the output produced by

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

は、 True 2 つのリテラルが同じ文字列インスタンスを参照しているためです。is True because the two literals refer to the same string instance.

挿入文字列リテラルInterpolated string literals

挿入文字列リテラルは文字列リテラルに似ていますが、とで区切られた穴を含み { } 、式が発生する可能性があります。Interpolated string literals are similar to string literals, but contain holes delimited by { and }, wherein expressions can occur. 実行時には、式は、テキスト形式を、穴が発生した場所の文字列に置き換えることを目的として評価されます。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. 文字列補間の構文とセマンティクスについては、「」 (挿入文字列) を参照してください。The syntax and semantics of string interpolation are described in section (Interpolated strings).

文字列リテラルと同様に、補間文字列リテラルは通常の場合も逐語的な場合もあります。Like string literals, interpolated string literals can be either regular or verbatim. 補間された正規文字列リテラルはとで区切られ、その後の $" " 文字列リテラルはとで区切られ $@" " ます。Interpolated regular string literals are delimited by $" and ", and interpolated verbatim string literals are delimited by $@" and ".

他のリテラルと同様に、補間文字列リテラルの字句解析では、次の文法に従って、最初に1つのトークンが生成されます。Like other literals, lexical analysis of an interpolated string literal initially results in a single token, as per the grammar below. ただし、構文分析の前に、補間文字列リテラルの1つのトークンは、穴を囲む文字列の部分に対して複数のトークンに分割されます。また、穴で発生する入力要素は、構文的に分析されされます。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. これにより、より多くの補間文字列リテラルが生成される可能性がありますが、構文が正しければ、最終的には、最終的には構文分析のためにトークンのシーケンスが処理されます。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)>'
    ;

Interpolated_string_literal トークンは、 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:

  • 次の出現箇所は、個別のトークンとして再解釈されます。これは、先頭の $ 符号、 interpolated_regular_string_wholeinterpolated_regular_string_startinterpolated_regular_string_midinterpolated_regular_string_endinterpolated_verbatim_string_wholeinterpolated_verbatim_string_startinterpolated_verbatim_string_mid、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.
  • これらの間の regular_balanced_textverbatim_balanced_text の発生は input_section (字句分析) として再処理され、結果として得られる入力要素のシーケンスとして再解釈されます。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. これらには、再解釈される補間文字列リテラルトークンが含まれている場合があります。These may in turn include interpolated string literal tokens to be reinterpreted.

構文分析は、トークンを interpolated_string_expression (挿入 文字列) に再結合します。Syntactic analysis will recombine the tokens into an interpolated_string_expression (Interpolated strings).

例 TODOExamples TODO

Null リテラルThe null literal

null_literal
    : 'null'
    ;

Null_literal は、参照型または null 許容型に暗黙的に変換できます。The null_literal can be implicitly converted to a reference type or nullable type.

演算子と区切り記号Operators and punctuators

いくつかの種類の演算子と区切り記号があります。There are several kinds of operators and punctuators. 演算子は、1 つ以上のオペランドに関係する操作を記述するために、式で使用されます。Operators are used in expressions to describe operations involving one or more operands. たとえば、式 a + b では、+ 演算子を使用して、a および b の 2 つのオペランドが追加されます。For example, the expression a + b uses the + operator to add the two operands a and b. 区切り記号は、グループ化と分離のためのものです。Punctuators are for grouping and separating.

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

right_shift
    : '>>'
    ;

right_shift_assignment
    : '>>='
    ;

Right_shiftright_shift_assignment の生産の縦棒を使用して、構文文法内の他の生産とは異なり、トークン間ではどのような種類の文字も使用できないことを示します。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. これらの生産は、 type_parameter_list s (型パラメーター) の適切な処理を可能にするために、特別に処理されます。These productions are treated specially in order to enable the correct handling of type_parameter_list s (Type parameters).

プリプロセスディレクティブPre-processing directives

プリプロセスディレクティブを使用すると、ソースファイルのセクションを条件付きでスキップしたり、エラーと警告の状態を報告したり、ソースコードの個別の領域を区切ることができます。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. "プリプロセスディレクティブ" という用語は、C および C++ プログラミング言語との一貫性を保つためにのみ使用されます。The term "pre-processing directives" is used only for consistency with the C and C++ programming languages. C# では、個別の処理前の手順はありません。プリプロセスディレクティブは、字句解析フェーズの一部として処理されます。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
    ;

次のプリプロセスディレクティブを使用できます。The following pre-processing directives are available:

  • #define とは、 #undef それぞれ条件付きコンパイルシンボル (宣言ディレクティブ) を定義および未定義にするために使用されます。#define and #undef, which are used to define and undefine, respectively, conditional compilation symbols (Declaration directives).
  • #if#elif#else 、および #endif 。ソースコードのセクションを条件付きでスキップするために使用されます (条件付きコンパイルディレクティブ)。#if, #elif, #else, and #endif, which are used to conditionally skip sections of source code (Conditional compilation directives).
  • #line。これは、エラーと警告 (行ディレクティブ) に対して出力される行番号を制御するために使用されます。#line, which is used to control line numbers emitted for errors and warnings (Line directives).
  • #error``#warningエラーと警告を発行するために使用されるおよび (診断ディレクティブ)。#error and #warning, which are used to issue errors and warnings, respectively (Diagnostic directives).
  • #region および #endregion 。ソースコード (Region ディレクティブ) のセクションを明示的にマークするために使用されます。#region and #endregion, which are used to explicitly mark sections of source code (Region directives).
  • #pragma。コンパイラに省略可能なコンテキスト情報 (プラグマディレクティブ) を指定するために使用されます。#pragma, which is used to specify optional contextual information to the compiler (Pragma directives).

プリプロセスディレクティブは、常にソースコードの個別の行を占有し、常に # 文字とプリプロセスディレクティブ名で始まります。A pre-processing directive always occupies a separate line of source code and always begins with a # character and a pre-processing directive name. 文字の前 # と、文字とディレクティブ名の間に空白がある場合があり # ます。White space may occur before the # character and between the # character and the directive name.

、、、、、、、またはディレクティブを含むソース行は、 #define #undef #if #elif #else #endif #line #endregion 単一行のコメントで終了する場合があります。A source line containing a #define, #undef, #if, #elif, #else, #endif, #line, or #endregion directive may end with a single-line comment. 区切られたコメント ( /* */ コメントのスタイル) は、プリプロセスディレクティブを含むソース行では許可されていません。Delimited comments (the /* */ style of comments) are not permitted on source lines containing pre-processing directives.

プリプロセスディレクティブは、トークンではなく、C# の構文文法の一部ではありません。Pre-processing directives are not tokens and are not part of the syntactic grammar of C#. ただし、プリプロセスディレクティブを使用して、トークンのシーケンスを含めたり除外したりできます。また、このようにして、C# プログラムの意味に影響を与えることができます。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. たとえば、コンパイルされると、プログラムは次のようになります。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
}

結果として、プログラムとまったく同じトークンのシーケンスが生成されます。results in the exact same sequence of tokens as the program:

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

したがって、構文的には、2つのプログラムはまったく異なっていますが、構文は同じです。Thus, whereas lexically, the two programs are quite different, syntactically, they are identical.

[条件付きコンパイル シンボル]Conditional compilation symbols

、、、およびの各ディレクティブによって提供される条件付きコンパイル機能 #if #elif は、 #else #endif 前処理式 (処理前の式) と条件付きコンパイルシンボルによって制御されます。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>'
    ;

条件付きコンパイルシンボルには、*defined _ または _ undefined * の2つの状態があります。A conditional compilation symbol has two possible states: defined _ or _undefined**. ソースファイルの字句処理の開始時に、条件付きコンパイルシンボルは、外部機構によって明示的に定義されていない限り、未定義になります (コマンドラインコンパイラオプションなど)。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). #defineディレクティブが処理されると、そのディレクティブで指定された条件付きコンパイルシンボルが、そのソースファイルで定義されます。When a #define directive is processed, the conditional compilation symbol named in that directive becomes defined in that source file. シンボルは、 #undef 同じシンボルのディレクティブが処理されるまで、またはソースファイルの末尾に到達するまで定義されたままになります。The symbol remains defined until an #undef directive for that same symbol is processed, or until the end of the source file is reached. これは、 #define #undef 1 つのソースファイル内のディレクティブとディレクティブが、同じプログラム内の他のソースファイルに影響を与えないことを意味します。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.

プリプロセス式で参照されている場合、定義済みの条件付きコンパイルシンボルにはブール値が含まれ、 true 未定義の条件付きコンパイルシンボルにはブール値が含まれ false ます。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. 条件付きコンパイルシンボルは、事前処理式で参照される前に明示的に宣言する必要はありません。There is no requirement that conditional compilation symbols be explicitly declared before they are referenced in pre-processing expressions. 代わりに、宣言されていないシンボルは単に未定義であるため、値が設定され false ます。Instead, undeclared symbols are simply undefined and thus have the value false.

条件付きコンパイルシンボルの名前空間は、C# プログラムでは、他のすべての名前付きエンティティとは区別されます。The name space for conditional compilation symbols is distinct and separate from all other named entities in a C# program. 条件付きコンパイルシンボルは #define 、および #undef ディレクティブおよびプリプロセス式でのみ参照できます。Conditional compilation symbols can only be referenced in #define and #undef directives and in pre-processing expressions.

処理前の式Pre-processing expressions

プリプロセス式は、ディレクティブおよびディレクティブで発生する可能性があり #if #elif ます。Pre-processing expressions can occur in #if and #elif directives. 処理前の式では、、、、およびの各演算子を ! == 使用でき != && || ます。また、かっこを使用してグループ化することもできます。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? ')'
    ;

プリプロセス式で参照されている場合、定義済みの条件付きコンパイルシンボルにはブール値が含まれ、 true 未定義の条件付きコンパイルシンボルにはブール値が含まれ false ます。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.

プリプロセス式の評価では、常にブール値が生成します。Evaluation of a pre-processing expression always yields a boolean value. プリプロセス式の評価の規則は、参照できるユーザー定義エンティティが条件付きコンパイルシンボルだけである点を除いて、定数式 (定数式) の評価ルールと同じです。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.

宣言ディレクティブDeclaration directives

宣言ディレクティブは、条件付きコンパイルシンボルを定義または未定義にするために使用されます。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
    ;

ディレクティブを処理すると、 #define 指定された条件付きコンパイルシンボルが定義されます。これは、ディレクティブの後のソース行から始まります。The processing of a #define directive causes the given conditional compilation symbol to become defined, starting with the source line that follows the directive. 同様に、ディレクティブの処理によって、 #undef 指定された条件付きコンパイルシンボルが未定義になります。これは、ディレクティブの後のソース行から始まります。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.

#define #undef ソースファイル内のディレクティブとディレクティブは、ソースファイル内の最初の トークン(トークン) の前に実行する必要があります。それ以外の場合は、コンパイル時エラーが発生します。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. 直感的に言う #define と、とディレクティブは、 #undef ソースファイル内の "実際のコード" の前に記述する必要があります。In intuitive terms, #define and #undef directives must precede any "real code" in the source file.

この例では、次の処理を実行します。The example:

#define Enterprise

#if Professional || Enterprise
    #define Advanced
#endif

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

は、 #define ソースファイル内の最初のトークン (キーワード) の前にディレクティブが指定されているため有効です namespaceis valid because the #define directives precede the first token (the namespace keyword) in the source file.

次の例では、が実際のコードに従うため、コンパイル時エラーが発生し #define ます。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
}

は、 #define 既に定義されている条件付きコンパイルシンボルを定義できますが、 #undef そのシンボルに介在するものはありません。A #define may define a conditional compilation symbol that is already defined, without there being any intervening #undef for that symbol. 次の例では、条件付きコンパイルシンボルを定義 A し、再度定義します。The example below defines a conditional compilation symbol A and then defines it again.

#define A
#define A

は、定義されて #undef いない条件付きコンパイルシンボルを "未定義" にすることがあります。A #undef may "undefine" a conditional compilation symbol that is not defined. 次の例では、条件付きコンパイルシンボルを定義 A し、2回未定義にします。2つ目は無効ですが、 #undef 有効ではありません。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

条件付きコンパイルディレクティブConditional compilation directives

条件付きコンパイルディレクティブは、ソースファイルの一部を条件付きで含めたり除外したりするために使用されます。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 #>'
    ;

構文で示されているように、条件付きコンパイルディレクティブは、ディレクティブ、ディレクティブ、0個以上のディレクティブ、 #if #elif 0 個または1個のディレクティブ、およびディレクティブで構成されるセットとして記述する必要があり #else #endif ます。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. ディレクティブは、ソースコードの条件付きセクションです。Between the directives are conditional sections of source code. 各セクションは、直前のディレクティブによって制御されます。Each section is controlled by the immediately preceding directive. 条件付きセクションには、これらのディレクティブが完全なセットを形成する、入れ子になった条件付きコンパイルディレクティブが含まれている場合があります。A conditional section may itself contain nested conditional compilation directives provided these directives form complete sets.

Pp_conditional は、通常の字句処理で、含まれている conditional_section s のうち最大1つを選択します。A pp_conditional selects at most one of the contained conditional_section s for normal lexical processing:

  • ディレクティブとディレクティブの pp_expression s #if は、1が #elif 生成されるまで評価され true ます。The pp_expression s of the #if and #elif directives are evaluated in order until one yields true. 式がを生成した場合 true 、対応するディレクティブの conditional_section が選択されます。If an expression yields true, the conditional_section of the corresponding directive is selected.
  • すべての pp_expression がを生成し、 false ディレクティブが存在する場合は、 #else ディレクティブの conditional_section #else が選択されます。If all pp_expression s yield false, and if an #else directive is present, the conditional_section of the #else directive is selected.
  • それ以外の場合、 conditional_section は選択されません。Otherwise, no conditional_section is selected.

選択した conditional_section(存在する場合) は、通常の input_section として処理されます。セクションに含まれているソースコードは、字句文法に従う必要があります。トークンは、セクションのソースコードから生成されます。また、セクションのプリプロセスディレクティブには、所定の効果があります。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.

残りの conditional_section s (存在する場合) は skipped_section s として処理されます。ただし、プリプロセスディレクティブの場合を除き、セクション内のソースコードは字句文法に準拠している必要はありません。セクションのソースコードからトークンは生成されません。また、セクションのプリプロセスディレクティブは構文的に正しい必要がありますが、それ以外の場合は処理されません。The remaining conditional_section s, if any, are processed as skipped_section s: 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. Skipped_section として処理されている conditional_section 内では、入れ子になった conditional_section s (入れ子になった... および... コンストラクトに含まれる #if #endif #region #endregion ) も skipped_section s として処理されます。Within a conditional_section that is being processed as a skipped_section, any nested conditional_section s (contained in nested #if...#endif and #region...#endregion constructs) are also processed as skipped_section s.

次の例は、条件付きコンパイルディレクティブを入れ子にする方法を示しています。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();
    }
}

プリプロセスディレクティブを除き、スキップされたソースコードは字句解析の対象になりません。Except for pre-processing directives, skipped source code is not subject to lexical analysis. たとえば、次の例では、セクションに未終了のコメントがあるにもかかわらず有効です #elseFor 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
    }
}

ただし、ソースコードのスキップされたセクションでも、プリプロセスディレクティブは構文的に正しい必要があることに注意してください。Note, however, that pre-processing directives are required to be lexically correct even in skipped sections of source code.

プリプロセスディレクティブは、複数行の入力要素内に出現する場合は処理されません。Pre-processing directives are not processed when they appear inside multi-line input elements. たとえば、次のようなプログラムがあるとします。For example, the program:

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

結果は次のようになります。results in the output:

hello,
#if Debug
        world
#else
        Nebraska
#endif

特別なケースでは、処理される前処理ディレクティブのセットは、 pp_expression の評価に依存する場合があります。In peculiar cases, the set of pre-processing directives that is processed might depend on the evaluation of the pp_expression. この例では、次の処理を実行します。The example:

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

class Q { } 、が定義されているかどうかに関係なく、常に同じトークンストリーム () を生成し X ます。always produces the same token stream (class Q { }), regardless of whether or not X is defined. が定義されている場合は、 X #if #endif 複数行のコメントにより、処理されるディレクティブはとだけです。If X is defined, the only processed directives are #if and #endif, due to the multi-line comment. Xが定義されていない場合、3つのディレクティブ ( #if#else#endif ) がディレクティブセットの一部になります。If X is undefined, then three directives (#if, #else, #endif) are part of the directive set.

診断ディレクティブDiagnostic directives

診断ディレクティブは、エラーメッセージと警告メッセージを明示的に生成するために使用されます。このメッセージは、他のコンパイル時のエラーや警告と同じ方法で報告されます。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
    ;

この例では、次の処理を実行します。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 {...}

は常に警告 ("チェックイン前に必要なコードレビュー") を生成し、条件付きシンボルとが両方とも定義されている場合は、コンパイル時エラー ("ビルドはデバッグとリテールの両方にすることはできません") を生成し Debug Retail ます。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. Pp_message には任意のテキストを含めることができることに注意してください。具体的には、単語内の単一引用符で示されているように、適切な形式のトークンが含まれている必要はありません can'tNote 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.

Region ディレクティブRegion directives

リージョンディレクティブは、ソースコードの領域を明示的にマークするために使用されます。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
    ;

領域には意味の意味がありません。地域は、プログラマが使用するためのものであり、ソースコードのセクションをマークする自動化ツールによって使用されます。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. またはディレクティブで指定されたメッセージは、同様に意味 #region #endregion がありません。リージョンを識別するためにのみ機能します。The message specified in a #region or #endregion directive likewise has no semantic meaning; it merely serves to identify the region. 一致 #region する #endregion ディレクティブとディレクティブには pp_message s が異なる場合があります。Matching #region and #endregion directives may have different pp_message s.

領域の字句処理は次のとおりです。The lexical processing of a region:

#region
...
#endregion

は、次の形式の条件付きコンパイルディレクティブの字句処理に正確に対応します。corresponds exactly to the lexical processing of a conditional compilation directive of the form:

#if true
...
#endif

行ディレクティブLine directives

行ディレクティブを使用すると、コンパイラによって警告やエラーなどの出力で報告され、呼び出し元情報属性 (呼び出し元情報属性) で使用される行番号とソースファイル名を変更できます。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).

行ディレクティブは、他のテキスト入力から C# ソースコードを生成するメタプログラミングツールで最もよく使用されます。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 ">'
    ;

#lineディレクティブが存在しない場合、コンパイラは出力に実際の行番号とソースファイル名を報告します。When no #line directives are present, the compiler reports true line numbers and source file names in its output. #line はない line_indicator を含むディレクティブを処理する場合 default 、コンパイラは、ディレクティブの後の行を指定された行番号 (および指定されている場合はファイル名) として扱います。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).

#line defaultディレクティブは、前のすべての #line ディレクティブの効果を反転させます。A #line default directive reverses the effect of all preceding #line directives. コンパイラは、ディレクティブが処理されていないかのように、後続の行の真の行情報を報告し #line ます。The compiler reports true line information for subsequent lines, precisely as if no #line directives had been processed.

ディレクティブは、 #line hidden エラーメッセージで報告されるファイルと行番号には影響しませんが、ソースレベルのデバッグに影響します。A #line hidden directive has no effect on the file and line numbers reported in error messages, but does affect source level debugging. デバッグ時に、 #line hidden ディレクティブとそれ以降のディレクティブの間のすべての行に #line 行番号情報がありません #line hiddenWhen debugging, all lines between a #line hidden directive and the subsequent #line directive (that is not #line hidden) have no line number information. デバッガーでコードをステップ実行すると、これらの行は完全にスキップされます。When stepping through code in the debugger, these lines will be skipped entirely.

File_name は、エスケープ文字が処理されないという点で、通常の文字列リテラルとは異なることに注意してください。" \ " 文字は、単に file_name 内の通常の円記号を指定します。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.

pragma ディレクティブPragma directives

#pragmaプリプロセスディレクティブは、コンパイラに対して省略可能なコンテキスト情報を指定するために使用されます。The #pragma preprocessing directive is used to specify optional contextual information to the compiler. ディレクティブで指定された情報は、 #pragma プログラムのセマンティクスを変更することはありません。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# には、 #pragma コンパイラの警告を制御するディレクティブが用意されています。C# provides #pragma directives to control compiler warnings. 言語の将来のバージョンには、追加のディレクティブが含まれる場合があり #pragma ます。Future versions of the language may include additional #pragma directives. 他の C# コンパイラとの相互運用性を確保するために、Microsoft C# コンパイラは不明なディレクティブに対してコンパイルエラーを発行しません。 #pragma ただし、このようなディレクティブでは警告が生成されます。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 warning

#pragma warningディレクティブは、後続のプログラムテキストのコンパイル中に、すべてまたは特定の警告メッセージのセットを無効化または復元するために使用されます。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+)*
    ;

#pragma warning警告リストを省略するディレクティブは、すべての警告に影響します。A #pragma warning directive that omits the warning list affects all warnings. #pragma warning警告リストを含むディレクティブは、一覧に指定されている警告のみに影響します。A #pragma warning directive that includes a warning list affects only those warnings that are specified in the list.

ディレクティブは、 #pragma warning disable すべてまたは特定の警告のセットを無効にします。A #pragma warning disable directive disables all or the given set of warnings.

ディレクティブは、 #pragma warning restore すべてまたは特定の警告のセットを、コンパイル単位の開始時に有効だった状態に復元します。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. 特定の警告が外部で無効にされた場合、 #pragma warning restore (すべての警告または特定の警告について) によって警告が再度有効になるわけではないことに注意してください。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.

次の例では、を使用し #pragma warning て、古いメンバーが参照されたときに、Microsoft C# コンパイラの警告番号を使用して報告された警告を一時的に無効にします。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
    }
}