ステートメントStatements

C# には、さまざまなステートメントが用意されています。C# provides a variety of statements. これらのステートメントのほとんどは、C および C++ でプログラミングする開発者にとって馴染み深いになります。Most of these statements will be familiar to developers who have programmed in C and C++.

statement
    : labeled_statement
    | declaration_statement
    | embedded_statement
    ;

embedded_statement
    : block
    | empty_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    | try_statement
    | checked_statement
    | unchecked_statement
    | lock_statement
    | using_statement
    | yield_statement
    | embedded_statement_unsafe
    ;

Embedded_statement非終端要素は他のステートメント内に表示されるステートメントを使用します。The embedded_statement nonterminal is used for statements that appear within other statements. 使用embedded_statementなくステートメント宣言ステートメントとラベル付きステートメントでこれらのコンテキストの使用は含まれません。The use of embedded_statement rather than statement excludes the use of declaration statements and labeled statements in these contexts. 例では、The example

void F(bool b) {
    if (b)
        int i = 44;
}

ため、コンパイル時エラーの結果、ifステートメントが必要です、 embedded_statementなくステートメント場合にそのブランチ。results in a compile-time error because an if statement requires an embedded_statement rather than a statement for its if branch. このコードが許可された場合、変数iは宣言されますが、使用することはありませんでした。If this code were permitted, then the variable i would be declared, but it could never be used. ただし、配置しているiの例が有効では、ブロックで宣言します。Note, however, that by placing i's declaration in a block, the example is valid.

エンドポイントと到達可能性End points and reachability

すべてのステートメントが、終点します。Every statement has an end point. 直感的な用語では、ステートメントの終了点は、ステートメントの直後に場所です。In intuitive terms, the end point of a statement is the location that immediately follows the statement. 複合ステートメント (埋め込みステートメントを含んでいるステートメント) の実行のルールは、コントロールが埋め込みステートメントの終点に達したときに行われるアクションを指定します。The execution rules for composite statements (statements that contain embedded statements) specify the action that is taken when control reaches the end point of an embedded statement. たとえば、コントロールには、ブロック内のステートメントの終了点に達すると、ブロックに次のステートメントに制御が移ります。For example, when control reaches the end point of a statement in a block, control is transferred to the next statement in the block.

ステートメントを実行してに可能性があることができます、ステートメントがあるとは到達します。If a statement can possibly be reached by execution, the statement is said to be reachable. 逆に、ステートメントが実行される可能性がない場合、ステートメントと呼ばれます到達できないします。Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable.

In the example

void F() {
    Console.WriteLine("reachable");
    goto Label;
    Console.WriteLine("unreachable");
    Label:
    Console.WriteLine("reachable");
}

2 番目の呼び出しのConsole.WriteLineステートメントが実行される可能性がないために到達できません。the second invocation of Console.WriteLine is unreachable because there is no possibility that the statement will be executed.

ステートメントに到達できることをコンパイラが判断した場合、警告が報告されます。A warning is reported if the compiler determines that a statement is unreachable. 具体的にはエラーではなく到達できないステートメントにすることをお勧めします。It is specifically not an error for a statement to be unreachable.

特定のステートメントまたはエンドポイントが到達可能かどうかを確認するのには、コンパイラは、各ステートメントに対して定義されている到達可能性の規則に従ってフロー分析を行います。To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. フロー解析では、定数式の値を考慮に入れます (定数式) ステートメントの動作を制御するが、非定数式で使用できる値は考慮されません。The flow analysis takes into account the values of constant expressions (Constant expressions) that control the behavior of statements, but the possible values of non-constant expressions are not considered. つまり、制御フロー分析のために、指定された型の非定数式がその型のすべての値を持つと見なされます。In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type.

In the example

void F() {
    const int i = 1;
    if (i == 2) Console.WriteLine("unreachable");
}

ブール式、ifために、ステートメントが定数式のオペランドは両方とも、==演算子は定数。the boolean expression of the if statement is a constant expression because both operands of the == operator are constants. 定数式は、コンパイル時に評価されるとは、値を生成falseConsole.WriteLine呼び出しは到達不能と見なされます。As the constant expression is evaluated at compile-time, producing the value false, the Console.WriteLine invocation is considered unreachable. ただし場合、iローカル変数にするのにはHowever, if i is changed to be a local variable

void F() {
    int i = 1;
    if (i == 2) Console.WriteLine("reachable");
}

Console.WriteLine実際が実行されない場合でも呼び出しが到達可能が考慮されます。the Console.WriteLine invocation is considered reachable, even though, in reality, it will never be executed.

ブロック関数のメンバーは常と見なされます到達します。The block of a function member is always considered reachable. ブロック内の各ステートメントの到達可能性の規則を連続して評価するには、任意のステートメントの到達可能性を判断できます。By successively evaluating the reachability rules of each statement in a block, the reachability of any given statement can be determined.

In the example

void F(int x) {
    Console.WriteLine("start");
    if (x < 0) Console.WriteLine("negative");
}

2 番目の到達可能性Console.WriteLineは次のように決定されます。the reachability of the second Console.WriteLine is determined as follows:

  • 最初のConsole.WriteLine式ステートメントに到達できるためのブロック、Fメソッドに到達します。The first Console.WriteLine expression statement is reachable because the block of the F method is reachable.
  • 1 つ目の終了点Console.WriteLineそのステートメントに到達するために、式のステートメントに到達します。The end point of the first Console.WriteLine expression statement is reachable because that statement is reachable.
  • ifステートメントは、最初の最後のポイントため到達Console.WriteLine式ステートメントに到達します。The if statement is reachable because the end point of the first Console.WriteLine expression statement is reachable.
  • 2 番目のConsole.WriteLine式ステートメントに到達できるためのブール式、ifステートメントには、定数の値はありません。falseします。The second Console.WriteLine expression statement is reachable because the boolean expression of the if statement does not have the constant value false.

2 つの状況に到達可能で、ステートメントの終了点のコンパイル時エラーがあります。There are two situations in which it is a compile-time error for the end point of a statement to be reachable:

  • switchステートメントでは、次の switch セクションに「フォール スルー」する switch セクションが許可されていませんはの switch セクションに到達可能で、ステートメント リストの終点のコンパイル時エラーです。Because the switch statement does not permit a switch section to "fall through" to the next switch section, it is a compile-time error for the end point of the statement list of a switch section to be reachable. 示す値では通常このエラーが発生した場合、breakステートメントがありません。If this error occurs, it is typically an indication that a break statement is missing.
  • 最後の位置に到達可能で値を計算する関数メンバーのブロックのコンパイル時エラーになります。It is a compile-time error for the end point of the block of a function member that computes a value to be reachable. 示す値を通常は、このエラーが発生した場合、returnステートメントがありません。If this error occurs, it typically is an indication that a return statement is missing.

ブロックBlocks

"ブロック" を使用すると、1 つのステートメントしか使用できないコンテキストで複数のステートメントを記述できます。A block permits multiple statements to be written in contexts where a single statement is allowed.

block
    : '{' statement_list? '}'
    ;

Aブロック省略可能なから成るstatement_list (ステートメントが一覧表示) 中かっこで囲まれている。A block consists of an optional statement_list (Statement lists), enclosed in braces. ステートメントの一覧を省略した場合、ブロックは空にすると言います。If the statement list is omitted, the block is said to be empty.

ブロックは、宣言ステートメントを含めることができます (宣言ステートメント)。A block may contain declaration statements (Declaration statements). ローカル変数または定数のスコープ、ブロックで宣言されているブロックです。The scope of a local variable or constant declared in a block is the block.

ブロックは、次のように実行されます。A block is executed as follows:

  • ブロックが空の場合、ブロックの終了ポイントに制御が移ります。If the block is empty, control is transferred to the end point of the block.
  • ブロックが空でない場合は、ステートメントの一覧に制御が移ります。If the block is not empty, control is transferred to the statement list. コントロールが、ステートメント リストの最後のポイントに達すると、コントロールは、ブロックの終了ポイントに転送されます。When and if control reaches the end point of the statement list, control is transferred to the end point of the block.

ブロックのステートメントの一覧は、到達可能なブロック自体が到達可能な場合です。The statement list of a block is reachable if the block itself is reachable.

ブロックが空の場合、またはステートメント リストのエンドポイントが到達可能な場合、ブロックの終了点が到達可能です。The end point of a block is reachable if the block is empty or if the end point of the statement list is reachable.

Aブロック1 つまたは複数を格納しているyieldステートメント (yield ステートメント)、反復子ブロックと呼ばれます。A block that contains one or more yield statements (The yield statement) is called an iterator block. 反復子ブロックは、反復子としての関数メンバーを実装するために使用 (反復子)。Iterator blocks are used to implement function members as iterators (Iterators). 反復子ブロックにいくつか追加の制限が適用されます。Some additional restrictions apply to iterator blocks:

  • コンパイル時エラーには、return反復子ブロックに表示されるステートメント (がyield returnステートメントは許可されます)。It is a compile-time error for a return statement to appear in an iterator block (but yield return statements are permitted).
  • Unsafe コンテキストを格納する反復子ブロックのコンパイル時エラーです (Unsafe コンテキスト)。It is a compile-time error for an iterator block to contain an unsafe context (Unsafe contexts). 反復子ブロックは、その宣言が、unsafe コンテキストで入れ子になった場合でも常に、安全なコンテキストを定義します。An iterator block always defines a safe context, even when its declaration is nested in an unsafe context.

ステートメントの一覧Statement lists

Aステートメント リストシーケンスで記述された 1 つまたは複数のステートメントで構成されます。A statement list consists of one or more statements written in sequence. 発生するステートメント リストブロックs (ブロック) し、 switch_blocks (switch ステートメント)。Statement lists occur in blocks (Blocks) and in switch_blocks (The switch statement).

statement_list
    : statement+
    ;

ステートメントの一覧は、最初のステートメントに制御を転送することによって実行されます。A statement list is executed by transferring control to the first statement. コントロールが、ステートメントの終了点に達すると、制御は次のステートメントに移ります。When and if control reaches the end point of a statement, control is transferred to the next statement. コントロールが最後のステートメントの終了点に達すると、コントロールは、ステートメント リストのエンドポイントに転送されます。When and if control reaches the end point of the last statement, control is transferred to the end point of the statement list.

ステートメントの一覧内のステートメントは、到達できるは、次の少なくとも 1 つが true の場合です。A statement in a statement list is reachable if at least one of the following is true:

  • ステートメントが最初のステートメントと、ステートメント リスト自体に到達します。The statement is the first statement and the statement list itself is reachable.
  • 前のステートメントの終了点に到達します。The end point of the preceding statement is reachable.
  • ステートメントはラベル付きステートメントであり、到達可能で、ラベルが参照されているgotoステートメント。The statement is a labeled statement and the label is referenced by a reachable goto statement.

一覧の最後のステートメントの終了点に到達できる場合、ステートメント リストの終点に到達します。The end point of a statement list is reachable if the end point of the last statement in the list is reachable.

空のステートメントThe empty statement

Empty_statement何も行われません。An empty_statement does nothing.

empty_statement
    : ';'
    ;

空のステートメントは、操作がないコンテキストで実行するステートメントが必要になるときに使用されます。An empty statement is used when there are no operations to perform in a context where a statement is required.

空のステートメントの実行は、単に、ステートメントの終了点にコントロールを転送します。Execution of an empty statement simply transfers control to the end point of the statement. したがって、空のステートメントの終了点は、到達可能な空のステートメントに到達できる場合は。Thus, the end point of an empty statement is reachable if the empty statement is reachable.

書き込み時に空のステートメントを使用できます、while本体のステートメント。An empty statement can be used when writing a while statement with a null body:

bool ProcessMessage() {...}

void ProcessMessages() {
    while (ProcessMessage())
        ;
}

空のステートメントを使用して、終了直前にラベルを宣言することも、"}"ブロックの。Also, an empty statement can be used to declare a label just before the closing "}" of a block:

void F() {
    ...
    if (done) goto exit;
    ...
    exit: ;
}

ラベル付きステートメントLabeled statements

A labeled_statementラベルによってプレフィックス指定するステートメントを許可します。A labeled_statement permits a statement to be prefixed by a label. ラベル付きステートメントはブロックでは、許可されますが、埋め込みステートメントとしては使用できません。Labeled statements are permitted in blocks, but are not permitted as embedded statements.

labeled_statement
    : identifier ':' statement
    ;

ラベル付きステートメントで指定された名前のラベルを宣言して、識別子します。A labeled statement declares a label with the name given by the identifier. ラベルのスコープは、ブロック全体を入れ子になったブロックを含め、ラベルが宣言されています。The scope of a label is the whole block in which the label is declared, including any nested blocks. 重複するスコープが同じ名前の 2 つのラベルのコンパイル時エラーになります。It is a compile-time error for two labels with the same name to have overlapping scopes.

ラベルはから参照できるgotoステートメント (goto ステートメント) ラベルのスコープ内で。A label can be referenced from goto statements (The goto statement) within the scope of the label. つまり、gotoステートメント ブロック内で、ブロック、もののブロックにないコントロールを転送できます。This means that goto statements can transfer control within blocks and out of blocks, but never into blocks.

ラベルは、独自の宣言領域があるし、他の識別子に干渉することはできません。Labels have their own declaration space and do not interfere with other identifiers. 例では、The example

int F(int x) {
    if (x >= 0) goto x;
    x = -x;
    x: return x;
}

有効であり、名前を使用してxパラメーターとラベルの両方として。is valid and uses the name x as both a parameter and a label.

ラベル付きステートメントの実行は、ラベルを次のステートメントの実行に正確に対応します。Execution of a labeled statement corresponds exactly to execution of the statement following the label.

ラベル付きステートメントに到達できるは、ラベルが、到達可能で参照されている場合にだけでなく通常の制御フローによって提供される到達可能性、gotoステートメント。In addition to the reachability provided by normal flow of control, a labeled statement is reachable if the label is referenced by a reachable goto statement. (例外。場合、goto内のステートメントは、tryを含む、finallyブロック、およびラベル付きステートメントが範囲外です、tryとの終点、finallyブロックにアクセスし、ラベル付きステートメントにから到達できませんgotoステートメントです)。(Exception: If a goto statement is inside a try that includes a finally block, and the labeled statement is outside the try, and the end point of the finally block is unreachable, then the labeled statement is not reachable from that goto statement.)

宣言ステートメントDeclaration statements

A declaration_statementローカル変数または定数を宣言します。A declaration_statement declares a local variable or constant. 宣言ステートメントはブロックでは、許可されますが、埋め込みステートメントとしては使用できません。Declaration statements are permitted in blocks, but are not permitted as embedded statements.

declaration_statement
    : local_variable_declaration ';'
    | local_constant_declaration ';'
    ;

ローカル変数の宣言Local variable declarations

A local_variable_declaration 1 つまたは複数のローカル変数を宣言します。A local_variable_declaration declares one or more local variables.

local_variable_declaration
    : local_variable_type local_variable_declarators
    ;

local_variable_type
    : type
    | 'var'
    ;

local_variable_declarators
    : local_variable_declarator
    | local_variable_declarators ',' local_variable_declarator
    ;

local_variable_declarator
    : identifier
    | identifier '=' local_variable_initializer
    ;

local_variable_initializer
    : expression
    | array_initializer
    | local_variable_initializer_unsafe
    ;

Local_variable_typelocal_variable_declarationか、直接、宣言によって導入される変数の型を指定しますまたは、識別子を持つことを示しますvarです初期化子に基づいて型を推論する必要があります。The local_variable_type of a local_variable_declaration either directly specifies the type of the variables introduced by the declaration, or indicates with the identifier var that the type should be inferred based on an initializer. 型がのリストが続くlocal_variable_declarators、新しい変数をそれぞれが導入されています。The type is followed by a list of local_variable_declarators, each of which introduces a new variable. A local_variable_declaratorから成る、識別子必要に応じて、変数の名前を示す、"="トークンとlocal_variable_initializer変数の初期値を提供します。A local_variable_declarator consists of an identifier that names the variable, optionally followed by an "=" token and a local_variable_initializer that gives the initial value of the variable.

コンテキスト キーワードとして、ローカル変数宣言のコンテキストで識別子 var が機能します (キーワード)。ときに、 local_variable_typeとして指定されてvarとという名前のない型varは宣言は、スコープ内、ローカル変数宣言を暗黙的に型指定された型があります。関連付け初期化子式の型から推論されます。In the context of a local variable declaration, the identifier var acts as a contextual keyword (Keywords).When the local_variable_type is specified as var and no type named var is in scope, the declaration is an implicitly typed local variable declaration, whose type is inferred from the type of the associated initializer expression. 暗黙的に型指定されたローカル変数の宣言は、次の制限が適用されます。Implicitly typed local variable declarations are subject to the following restrictions:

  • Local_variable_declaration複数を含めることはできませんlocal_variable_declarator秒。The local_variable_declaration cannot include multiple local_variable_declarators.
  • Local_variable_declarator含める必要があります、 local_variable_initializerします。The local_variable_declarator must include a local_variable_initializer.
  • Local_variable_initializer必要があります、します。The local_variable_initializer must be an expression.
  • 初期化子コンパイル時の型があります。The initializer expression must have a compile-time type.
  • 初期化子自体、宣言された変数は参照できませんThe initializer expression cannot refer to the declared variable itself

正しくない暗黙的に型指定されたローカル変数宣言の例を次に示します。The following are examples of incorrect implicitly typed local variable declarations:

var x;               // Error, no initializer to infer type from
var y = {1, 2, 3};   // Error, array initializer not permitted
var z = null;        // Error, null does not have a type
var u = x => x + 1;  // Error, anonymous functions do not have a type
var v = v++;         // Error, initializer cannot refer to variable itself

ローカル変数の値が使用する式で取得した、 simple_name (簡易名) を使用してローカル変数の値を変更し、割り当て(代入演算子)。The value of a local variable is obtained in an expression using a simple_name (Simple names), and the value of a local variable is modified using an assignment (Assignment operators). ローカル変数を明示的に代入する必要があります (確実な代入) 各場所、その値を取得します。A local variable must be definitely assigned (Definite assignment) at each location where its value is obtained.

宣言されたローカル変数のスコープをlocal_variable_declarationブロックで宣言が発生します。The scope of a local variable declared in a local_variable_declaration is the block in which the declaration occurs. 前にあるテキストの位置にローカル変数を参照するとエラーには、 local_variable_declaratorのローカル変数。It is an error to refer to a local variable in a textual position that precedes the local_variable_declarator of the local variable. ローカル変数のスコープ内では、別のローカル変数や定数を同じ名前で宣言すると、コンパイル時エラーを勧めします。Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.

複数の変数を宣言して、ローカル変数の宣言は、同じ型を持つ 1 つの変数の複数の宣言と同じです。A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type. さらに、ローカル変数宣言で変数の初期化子は、宣言の直後に挿入されている代入ステートメントに正確に対応します。Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration.

例では、The example

void F() {
    int x = 1, y, z = x * 2;
}

対応します。corresponds exactly to

void F() {
    int x; x = 1;
    int y;
    int z; z = x * 2;
}

暗黙的に型指定されたローカル変数宣言で宣言されているローカル変数の型を表示して、変数を初期化するために使用する式の型と同じであります。In an implicitly typed local variable declaration, the type of the local variable being declared is taken to be the same as the type of the expression used to initialize the variable. 例:For example:

var i = 5;
var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();

上、暗黙的に型指定されたローカル変数宣言は、明示的に型指定された次の宣言にまったく同じです。The implicitly typed local variable declarations above are precisely equivalent to the following explicitly typed declarations:

int i = 5;
string s = "Hello";
double d = 1.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new Dictionary<int,Order>();

ローカル定数宣言Local constant declarations

A local_constant_declaration 1 つまたは複数のローカル定数を宣言します。A local_constant_declaration declares one or more local constants.

local_constant_declaration
    : 'const' type constant_declarators
    ;

constant_declarators
    : constant_declarator (',' constant_declarator)*
    ;

constant_declarator
    : identifier '=' constant_expression
    ;

local_constant_declaration宣言によって導入される定数の型を指定します。The type of a local_constant_declaration specifies the type of the constants introduced by the declaration. 型がのリストが続くconstant_declarators、新しい定数をそれぞれが導入されています。The type is followed by a list of constant_declarators, each of which introduces a new constant. A constant_declaratorから成る、識別子でその名前、定数の後に、"="トークン、その後に、 constant_expression (定数式)、定数の値を提供します。A constant_declarator consists of an identifier that names the constant, followed by an "=" token, followed by a constant_expression (Constant expressions) that gives the value of the constant.

constant_expressionローカル定数宣言の定数メンバー宣言のものと同じ規則に従う必要があります (定数)。The type and constant_expression of a local constant declaration must follow the same rules as those of a constant member declaration (Constants).

ローカル定数の値が使用する式で取得した、 simple_name (簡易名)。The value of a local constant is obtained in an expression using a simple_name (Simple names).

ローカル定数のスコープは、ブロックの宣言が発生します。The scope of a local constant is the block in which the declaration occurs. 前にあるテキストの位置でのローカル定数を参照するとエラーにはそのconstant_declaratorします。It is an error to refer to a local constant in a textual position that precedes its constant_declarator. ローカル定数のスコープ内では、別のローカル変数や定数を同じ名前で宣言すると、コンパイル時エラーを勧めします。Within the scope of a local constant, it is a compile-time error to declare another local variable or constant with the same name.

複数の定数を宣言するためのローカル定数宣言では、単一の定数のと同じ型の複数の宣言に相当します。A local constant declaration that declares multiple constants is equivalent to multiple declarations of single constants with the same type.

式ステートメントExpression statements

Expression_statement指定された式を評価します。An expression_statement evaluates a given expression. 値は、式で計算、存在する場合は破棄されます。The value computed by the expression, if any, is discarded.

expression_statement
    : statement_expression ';'
    ;

statement_expression
    : invocation_expression
    | null_conditional_invocation_expression
    | object_creation_expression
    | assignment
    | post_increment_expression
    | post_decrement_expression
    | pre_increment_expression
    | pre_decrement_expression
    | await_expression
    ;

ステートメントとしては、すべての式を使用します。Not all expressions are permitted as statements. など、特定の式でx + yx == 1ことだけです (これは破棄されます) 値を計算する、ステートメントとしては使用できません。In particular, expressions such as x + y and x == 1 that merely compute a value (which will be discarded), are not permitted as statements.

実行、 expression_statement内の式を評価しの終点に制御を転送、 expression_statementします。Execution of an expression_statement evaluates the contained expression and then transfers control to the end point of the expression_statement. 終点をexpression_statementが到達可能な場合は、そのexpression_statementに到達します。The end point of an expression_statement is reachable if that expression_statement is reachable.

選択ステートメントSelection statements

選択ステートメントでは、いくつかの式の値に基づいて、実行可能ステートメントの数値の 1 つを選択します。Selection statements select one of a number of possible statements for execution based on the value of some expression.

selection_statement
    : if_statement
    | switch_statement
    ;

If ステートメントThe if statement

ifステートメントは、ブール式の値に基づいて実行するステートメントを選択します。The if statement selects a statement for execution based on the value of a boolean expression.

if_statement
    : 'if' '(' boolean_expression ')' embedded_statement
    | 'if' '(' boolean_expression ')' embedded_statement 'else' embedded_statement
    ;

elseパーツは構文的に最も近い先行関連付けif構文で許可されています。An else part is associated with the lexically nearest preceding if that is allowed by the syntax. つまり、if形式のステートメントThus, an if statement of the form

if (x) if (y) F(); else G();

上記の式は、次の式と同じです。is equivalent to

if (x) {
    if (y) {
        F();
    }
    else {
        G();
    }
}

ifステートメントが次のように実行されます。An if statement is executed as follows:

  • Boolean_expression (ブール式) が評価されます。The boolean_expression (Boolean expressions) is evaluated.
  • ブール式の結果が場合true、埋め込みの最初のステートメントに制御が移ります。If the boolean expression yields true, control is transferred to the first embedded statement. コントロールがの終了ポイントに転送されるコントロールがそのステートメントの終了点に達すると、ifステートメント。When and if control reaches the end point of that statement, control is transferred to the end point of the if statement.
  • ブール式の結果が場合false場合に、else部分が存在する、2 番目の埋め込みステートメントに制御が移ります。If the boolean expression yields false and if an else part is present, control is transferred to the second embedded statement. コントロールがの終了ポイントに転送されるコントロールがそのステートメントの終了点に達すると、ifステートメント。When and if control reaches the end point of that statement, control is transferred to the end point of the if statement.
  • ブール式の結果が場合false場合に、else部分が存在しないの終点に制御が移ります、ifステートメント。If the boolean expression yields false and if an else part is not present, control is transferred to the end point of the if statement.

最初のステートメントの埋め込み、ifステートメントに到達できる場合、ifステートメントに到達でき、ブール型の式が定数の値を持たないfalseします。The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false.

2 番目のステートメントの埋め込み、ifステートメントで存在する場合の指定が到達可能な場合、ifステートメントに到達でき、ブール型の式が定数の値を持たないtrueします。The second embedded statement of an if statement, if present, is reachable if the if statement is reachable and the boolean expression does not have the constant value true.

終点をifステートメントが到達可能な場合、その埋め込みステートメントの少なくとも 1 つの終点に到達します。The end point of an if statement is reachable if the end point of at least one of its embedded statements is reachable. 末尾がさらに、ポイント、ifステートメントなしでelse部品に到達できる場合、ifステートメントに到達でき、ブール型の式が定数の値を持たないtrueIn addition, the end point of an if statement with no else part is reachable if the if statement is reachable and the boolean expression does not have the constant value true.

Switch ステートメントThe switch statement

Switch ステートメントは、実行の switch 式の値に対応するスイッチが関連付けられているラベルを持つステートメントの一覧を選択します。The switch statement selects for execution a statement list having an associated switch label that corresponds to the value of the switch expression.

switch_statement
    : 'switch' '(' expression ')' switch_block
    ;

switch_block
    : '{' switch_section* '}'
    ;

switch_section
    : switch_label+ statement_list
    ;

switch_label
    : 'case' constant_expression ':'
    | 'default' ':'
    ;

A switch_statementキーワードから成るswitchの後にかっこで囲まれた式が (switch 式と呼ばれます)、その後、 switch_blockします。A switch_statement consists of the keyword switch, followed by a parenthesized expression (called the switch expression), followed by a switch_block. Switch_block 0 個以上から成るswitch_sections、中かっこで囲みます。The switch_block consists of zero or more switch_sections, enclosed in braces. switch_section 1 つまたは複数から成るswitch_label秒後に、 statement_list (ステートメントが一覧表示)。Each switch_section consists of one or more switch_labels followed by a statement_list (Statement lists).

の種類を制御するswitchステートメントは、switch 式で確立されます。The governing type of a switch statement is established by the switch expression.

  • Switch 式の型が場合sbytebyteshortushortintuintlongulongboolcharstring、または、 enum_typeのかどうかは、これらの型のいずれかに対応する null 許容型では、管理方法はまたはの入力、switchステートメント。If the type of the switch expression is sbyte, byte, short, ushort, int, uint, long, ulong, bool, char, string, or an enum_type, or if it is the nullable type corresponding to one of these types, then that is the governing type of the switch statement.
  • それ以外の場合、1 つだけユーザー定義の暗黙の変換 (ユーザー定義の変換) switch 式の型から型を制御する次の候補のいずれかに存在する必要があります: sbytebyteshortushortintuintlongulongcharstring、またはそれらの型のいずれかに対応する null 許容型。Otherwise, exactly one user-defined implicit conversion (User-defined conversions) must exist from the type of the switch expression to one of the following possible governing types: sbyte, byte, short, ushort, int, uint, long, ulong, char, string, or, a nullable type corresponding to one of those types.
  • それ以外の場合、このような暗黙的な変換が存在しないか、このような 1 つの暗黙的な変換が存在する数より多い場合、コンパイル時エラーが発生します。Otherwise, if no such implicit conversion exists, or if more than one such implicit conversion exists, a compile-time error occurs.

それぞれの定数式caseラベルは、暗黙的に変換する値を表す必要があります (暗黙的な変換) の管理の型をswitchステートメント。The constant expression of each case label must denote a value that is implicitly convertible (Implicit conversions) to the governing type of the switch statement. 2 つ以上の場合、コンパイル時エラーが発生したcase同じラベルswitchステートメントで同じ定数値を指定します。A compile-time error occurs if two or more case labels in the same switch statement specify the same constant value.

最大で 1 つできますdefaultswitch ステートメントでラベル。There can be at most one default label in a switch statement.

Aswitchステートメントが次のように実行されます。A switch statement is executed as follows:

  • Switch 式が評価され、管理の型に変換します。The switch expression is evaluated and converted to the governing type.
  • 定数のいずれかが指定されている場合、case同じラベルswitchステートメントが switch 式の値と等しく、一致する、次のステートメントの一覧に制御が移りますcaseラベル。If one of the constants specified in a case label in the same switch statement is equal to the value of the switch expression, control is transferred to the statement list following the matched case label.
  • 場合に指定された定数のいずれもcase同じラベルswitchステートメントは、switch 式の値と等しい場合に、defaultラベルが存在する、ステートメント リストの次に制御が移ります、 defaultラベル。If none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if a default label is present, control is transferred to the statement list following the default label.
  • 場合に指定された定数のいずれもcase同じラベルswitchステートメントは、switch 式の値と等しいされていない場合defaultラベルが存在するの終点に制御が移ります、switchステートメント。If none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if no default label is present, control is transferred to the end point of the switch statement.

Switch セクションのステートメント リストのエンドポイントが到達可能な場合は、コンパイル時エラーが発生します。If the end point of the statement list of a switch section is reachable, a compile-time error occurs. これは、「フォール スルー」ルールと呼ばれます。This is known as the "no fall through" rule. 例では、The example

switch (i) {
case 0:
    CaseZero();
    break;
case 1:
    CaseOne();
    break;
default:
    CaseOthers();
    break;
}

switch セクションに到達可能なエンドポイントがあるないため、このプロパティの値は有効です。is valid because no switch section has a reachable end point. C や C++ とは異なり、switch セクションの実行は許可されていません「フォール スルー」に次の switch セクションを例では、Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example

switch (i) {
case 0:
    CaseZero();
case 1:
    CaseZeroOrOne();
default:
    CaseAny();
}

コンパイル時エラーが発生します。results in a compile-time error. Switch セクションの実行が明示的なもう 1 つの switch セクションの実行後に、goto caseまたはgoto defaultステートメントを使用する必要があります。When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:

switch (i) {
case 0:
    CaseZero();
    goto case 1;
case 1:
    CaseZeroOrOne();
    goto default;
default:
    CaseAny();
    break;
}

複数のラベルが許可されている、 switch_sectionします。Multiple labels are permitted in a switch_section. 例では、The example

switch (i) {
case 0:
    CaseZero();
    break;
case 1:
    CaseOne();
    break;
case 2:
default:
    CaseTwo();
    break;
}

有効です。is valid. この例ではためにを「フォール スルー」ルールに違反しないラベルcase 2:default:同じの一部であるswitch_sectionします。The example does not violate the "no fall through" rule because the labels case 2: and default: are part of the same switch_section.

「フォール スルー」ルールが C および C++ で発生するバグの一般的なクラスとbreakステートメントが誤ってを省略するとします。The "no fall through" rule prevents a common class of bugs that occur in C and C++ when break statements are accidentally omitted. さらに、このルールでは、switch セクションにより、switchステートメントにステートメントの動作に影響を与えずに任意に置くことです。In addition, because of this rule, the switch sections of a switch statement can be arbitrarily rearranged without affecting the behavior of the statement. セクションなど、switch上記のステートメントは、ステートメントの動作に影響を与えずに元に戻すことができます。For example, the sections of the switch statement above can be reversed without affecting the behavior of the statement:

switch (i) {
default:
    CaseAny();
    break;
case 1:
    CaseZeroOrOne();
    goto default;
case 0:
    CaseZero();
    goto case 1;
}

Switch セクションのステートメントの一覧は、通常で終わる、 breakgoto case、またはgoto defaultステートメントが到達できないステートメント リストの最後のポイントを表示する構成要素を許可します。The statement list of a switch section typically ends in a break, goto case, or goto default statement, but any construct that renders the end point of the statement list unreachable is permitted. たとえば、whileブール式で制御ステートメントtrueエンドポイントに正常には到達しません。For example, a while statement controlled by the boolean expression true is known to never reach its end point. 同様に、throwまたはreturnステートメントが常に別の場所に制御を転送し、その終点に到達しません。Likewise, a throw or return statement always transfers control elsewhere and never reaches its end point. したがって、次の例では有効です。Thus, the following example is valid:

switch (i) {
case 0:
    while (true) F();
case 1:
    throw new ArgumentException();
case 2:
    return;
}

管理の型をswitchステートメントは、型、stringします。The governing type of a switch statement may be the type string. 例:For example:

void DoCommand(string command) {
    switch (command.ToLower()) {
    case "run":
        DoRun();
        break;
    case "save":
        DoSave();
        break;
    case "quit":
        DoQuit();
        break;
    default:
        InvalidCommand(command);
        break;
    }
}

などの文字列の等値演算子 (文字列等値演算子)、switchステートメントが大文字小文字を区別し、switch 式の文字列が完全に一致する場合にのみに指定されたスイッチ セクションを実行するcaseラベル定数。Like the string equality operators (String equality operators), the switch statement is case sensitive and will execute a given switch section only if the switch expression string exactly matches a case label constant.

管理方法が入力すると、switchステートメントがstring、値nullcase ラベル定数として許可されます。When the governing type of a switch statement is string, the value null is permitted as a case label constant.

Statement_listの s をswitch_block宣言ステートメントを含めることができます (宣言ステートメント)。The statement_lists of a switch_block may contain declaration statements (Declaration statements). ローカル変数または定数のスコープの switch ブロックで宣言されている、スイッチ ブロックです。The scope of a local variable or constant declared in a switch block is the switch block.

Switch セクションのステートメントの一覧に到達できる場合、switchステートメントに到達し、次の少なくとも 1 つが true:The statement list of a given switch section is reachable if the switch statement is reachable and at least one of the following is true:

  • Switch 式は、非定数値です。The switch expression is a non-constant value.
  • Switch 式が定数の値と一致する、 case switch セクション内のラベル。The switch expression is a constant value that matches a case label in the switch section.
  • Switch 式は定数値と一致しないcaseラベル、および switch セクションが含まれています、defaultラベル。The switch expression is a constant value that doesn't match any case label, and the switch section contains the default label.
  • Switch セクションの switch ラベルは、到達によって参照されるgoto caseまたはgoto defaultステートメント。A switch label of the switch section is referenced by a reachable goto case or goto default statement.

終点をswitchステートメントに到達できるは、次の少なくとも 1 つが true の場合。The end point of a switch statement is reachable if at least one of the following is true:

  • switchステートメントが含まれていますが、到達可能なbreakを終了させるステートメント、switchステートメント。The switch statement contains a reachable break statement that exits the switch statement.
  • switchステートメントに到達、switch 式は非定数値、および nodefaultラベルが存在します。The switch statement is reachable, the switch expression is a non-constant value, and no default label is present.
  • switchステートメントに到達、switch 式は定数値と一致しないcaseラベル、および nodefaultラベルが存在します。The switch statement is reachable, the switch expression is a constant value that doesn't match any case label, and no default label is present.

繰り返しステートメントIteration statements

繰り返しステートメントでは、埋め込みステートメントを繰り返し実行します。Iteration statements repeatedly execute an embedded statement.

iteration_statement
    : while_statement
    | do_statement
    | for_statement
    | foreach_statement
    ;

While ステートメントThe while statement

whileステートメントは条件付きで 0 回以上の埋め込みステートメントを実行します。The while statement conditionally executes an embedded statement zero or more times.

while_statement
    : 'while' '(' boolean_expression ')' embedded_statement
    ;

Awhileステートメントが次のように実行されます。A while statement is executed as follows:

  • Boolean_expression (ブール式) が評価されます。The boolean_expression (Boolean expressions) is evaluated.
  • ブール式の結果が場合true、埋め込みステートメントに制御が移ります。If the boolean expression yields true, control is transferred to the embedded statement. コントロールが埋め込みステートメントの終了点に達すると (通常の実行から、continueステートメント) の先頭に制御が移ります、whileステートメント。When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), control is transferred to the beginning of the while statement.
  • ブール式の結果が場合falseの終点に制御が移ります、whileステートメント。If the boolean expression yields false, control is transferred to the end point of the while statement.

内の埋め込みステートメントをwhileステートメントをbreakステートメント (break ステートメント) の終点に制御を転送できる、 while (埋め込みの繰り返しを終了するステートメントステートメントの場合)、およびcontinueステートメント (continue ステートメント) に埋め込みステートメントの終了ポイントに制御を移すことができます (の別のイテレーションを実行するため、whileステートメント)。Within the embedded statement of a while statement, a break statement (The break statement) may be used to transfer control to the end point of the while statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement (thus performing another iteration of the while statement).

埋め込みステートメントをwhileステートメントに到達できる場合、whileステートメントに到達でき、ブール型の式が定数の値を持たないfalseします。The embedded statement of a while statement is reachable if the while statement is reachable and the boolean expression does not have the constant value false.

終点をwhileステートメントに到達できるは、次の少なくとも 1 つが true の場合。The end point of a while statement is reachable if at least one of the following is true:

  • whileステートメントが含まれていますが、到達可能なbreakを終了させるステートメント、whileステートメント。The while statement contains a reachable break statement that exits the while statement.
  • whileステートメントに到達でき、ブール型の式が定数の値を持たないtrueします。The while statement is reachable and the boolean expression does not have the constant value true.

Do ステートメントThe do statement

doステートメントは条件付きで 1 回以上の埋め込みステートメントを実行します。The do statement conditionally executes an embedded statement one or more times.

do_statement
    : 'do' embedded_statement 'while' '(' boolean_expression ')' ';'
    ;

Adoステートメントが次のように実行されます。A do statement is executed as follows:

  • 埋め込みステートメントには、制御が移ります。Control is transferred to the embedded statement.
  • コントロールが埋め込みステートメントの終了点に達すると (通常の実行から、continueステートメント)、 boolean_expression (ブール式) が評価されます。When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the boolean_expression (Boolean expressions) is evaluated. ブール式の結果が場合trueの先頭に制御が移ります、doステートメント。If the boolean expression yields true, control is transferred to the beginning of the do statement. 終点に制御が移ります、それ以外の場合、doステートメント。Otherwise, control is transferred to the end point of the do statement.

内の埋め込みステートメントをdoステートメントをbreakステートメント (break ステートメント) の終点に制御を転送できる、 do (埋め込みの繰り返しを終了するステートメントステートメントの場合)、およびcontinueステートメント (continue ステートメント) に埋め込みステートメントの終了ポイントに制御を移すことができます。Within the embedded statement of a do statement, a break statement (The break statement) may be used to transfer control to the end point of the do statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement.

埋め込みステートメントをdoステートメントに到達できる場合、doステートメントに到達します。The embedded statement of a do statement is reachable if the do statement is reachable.

終点をdoステートメントに到達できるは、次の少なくとも 1 つが true の場合。The end point of a do statement is reachable if at least one of the following is true:

  • doステートメントが含まれていますが、到達可能なbreakを終了させるステートメント、doステートメント。The do statement contains a reachable break statement that exits the do statement.
  • 埋め込みステートメントの終了ポイントに到達でき、ブール型の式が定数の値を持たないtrueします。The end point of the embedded statement is reachable and the boolean expression does not have the constant value true.

For ステートメントThe for statement

forステートメント一連の初期化式を評価し、条件が true の場合、繰り返し埋め込みステートメントを実行し、一連の反復式を評価します。The for statement evaluates a sequence of initialization expressions and then, while a condition is true, repeatedly executes an embedded statement and evaluates a sequence of iteration expressions.

for_statement
    : 'for' '(' for_initializer? ';' for_condition? ';' for_iterator? ')' embedded_statement
    ;

for_initializer
    : local_variable_declaration
    | statement_expression_list
    ;

for_condition
    : boolean_expression
    ;

for_iterator
    : statement_expression_list
    ;

statement_expression_list
    : statement_expression (',' statement_expression)*
    ;

For_initializer存在する場合は、いずれかで構成されています、 local_variable_declaration (ローカル変数宣言) の一覧またはstatement_式s (式ステートメント) コンマで区切られました。The for_initializer, if present, consists of either a local_variable_declaration (Local variable declarations) or a list of statement_expressions (Expression statements) separated by commas. 宣言されたローカル変数のスコープをfor_initializerから始まり、 local_variable_declarator変数の埋め込みステートメントの最後までを対象とします。The scope of a local variable declared by a for_initializer starts at the local_variable_declarator for the variable and extends to the end of the embedded statement. スコープに含まれる、 for_conditionfor_iteratorします。The scope includes the for_condition and the for_iterator.

For_conditionがある場合があります、 boolean_expression (ブール式)。The for_condition, if present, must be a boolean_expression (Boolean expressions).

For_iterator存在する場合は、一覧から成るstatement_expressions (式ステートメント) コンマで区切られました。The for_iterator, if present, consists of a list of statement_expressions (Expression statements) separated by commas.

次のように FOR ステートメントを実行します。A for statement is executed as follows:

  • 場合、 for_initializerが存在する場合は、変数の初期化子またはステートメントの式が記述されている順序で実行されます。If a for_initializer is present, the variable initializers or statement expressions are executed in the order they are written. この手順は一度だけ実行します。This step is only performed once.
  • 場合、 for_conditionが存在する場合は、評価されます。If a for_condition is present, it is evaluated.
  • 場合、 for_conditionが存在するか、評価が得られますtrue、埋め込みステートメントに制御が移ります。If the for_condition is not present or if the evaluation yields true, control is transferred to the embedded statement. コントロールが埋め込みステートメントの終了点に達すると (通常の実行から、continueステートメント) の式、 for_iteratorシーケンスで、いずれかが評価され、その他のイテレーションは場合は、以降の評価では、実行、 for_condition前の手順でします。When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the expressions of the for_iterator, if any, are evaluated in sequence, and then another iteration is performed, starting with evaluation of the for_condition in the step above.
  • 場合、 for_conditionが存在し、評価が得られますfalseの終点に制御が移ります、forステートメント。If the for_condition is present and the evaluation yields false, control is transferred to the end point of the for statement.

内の埋め込みステートメントをforステートメントをbreakステートメント (break ステートメント) の終点に制御を転送できる、 for (埋め込みの繰り返しを終了するステートメントステートメントの場合)、およびcontinueステートメント (continue ステートメント) に埋め込みステートメントの終了ポイントに制御を移すことができます (実行するため、 for_iteratorと別のイテレーションを実行する、forステートメントでは、以降では、 for_condition)。Within the embedded statement of a for statement, a break statement (The break statement) may be used to transfer control to the end point of the for statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement (thus executing the for_iterator and performing another iteration of the for statement, starting with the for_condition).

埋め込みステートメントをforステートメントに到達できるは、次のいずれかが true の場合。The embedded statement of a for statement is reachable if one of the following is true:

  • forステートメントに到達しないとfor_conditionが存在します。The for statement is reachable and no for_condition is present.
  • forステートメントに到達し、 for_conditionが存在し、定数の値を持たないfalseします。The for statement is reachable and a for_condition is present and does not have the constant value false.

終点をforステートメントに到達できるは、次の少なくとも 1 つが true の場合。The end point of a for statement is reachable if at least one of the following is true:

  • forステートメントが含まれていますが、到達可能なbreakを終了させるステートメント、forステートメント。The for statement contains a reachable break statement that exits the for statement.
  • forステートメントに到達し、 for_conditionが存在し、定数の値を持たないtrueします。The for statement is reachable and a for_condition is present and does not have the constant value true.

Foreach ステートメントThe foreach statement

foreachステートメントは、コレクションの各要素に対して埋め込みステートメントを実行し、コレクションの要素を列挙します。The foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.

foreach_statement
    : 'foreach' '(' local_variable_type identifier 'in' expression ')' embedded_statement
    ;

識別子foreachステートメントの宣言、反復変数ステートメントの。The type and identifier of a foreach statement declare the iteration variable of the statement. 場合、varとして識別子が指定されて、 local_variable_type、という名前のない型とvarがスコープ内の反復変数と呼ばれます、暗黙的に型指定された繰り返し変数、その型がの要素の型にして、foreachステートメントは、以下のようです。If the var identifier is given as the local_variable_type, and no type named var is in scope, the iteration variable is said to be an implicitly typed iteration variable, and its type is taken to be the element type of the foreach statement, as specified below. 反復変数は、埋め込みステートメントを拡張するスコープを持つ読み取り専用のローカル変数に対応します。The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. 実行中に、foreachステートメントでは、繰り返し変数は、イテレーションが現在実行中のコレクションの要素を表します。During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. 埋め込みステートメントを繰り返し変数を変更しようとすると、コンパイル時エラーが発生します (割り当てまたは++--演算子) として繰り返し変数を渡すことも、refまたはoutパラメーター。A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and -- operators) or pass the iteration variable as a ref or out parameter.

次に、簡潔にするため、 IEnumerableIEnumeratorIEnumerable<T>IEnumerator<T>名前空間に対応する型を参照してくださいSystem.CollectionsSystem.Collections.Genericします。In the following, for brevity, IEnumerable, IEnumerator, IEnumerable<T> and IEnumerator<T> refer to the corresponding types in the namespaces System.Collections and System.Collections.Generic.

Foreach ステートメントのコンパイル時の処理が最初に決定します、コレクション型列挙子の型要素型の式。The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. この決定は、次のように処理されます。This determination proceeds as follows:

  • 場合、型Xが配列型からの暗黙的な参照変換はXIEnumerableインターフェイス (ためSystem.Arrayこのインターフェイスを実装)。If the type X of expression is an array type then there is an implicit reference conversion from X to the IEnumerable interface (since System.Array implements this interface). コレクション型は、IEnumerableインターフェイスを列挙子の型は、IEnumeratorインターフェイスと要素型の要素の型が、配列型Xします。The collection type is the IEnumerable interface, the enumerator type is the IEnumerator interface and the element type is the element type of the array type X.

  • 場合、型Xdynamicからの暗黙的な変換はIEnumerableインターフェイス (暗黙的な動的変換)。If the type X of expression is dynamic then there is an implicit conversion from expression to the IEnumerable interface (Implicit dynamic conversions). コレクション型は、IEnumerableインターフェイスと列挙子の型は、IEnumeratorインターフェイス。The collection type is the IEnumerable interface and the enumerator type is the IEnumerator interface. 場合、varとして識別子が指定されて、 local_variable_type要素型dynamic、それ以外の場合はobjectします。If the var identifier is given as the local_variable_type then the element type is dynamic, otherwise it is object.

  • それ以外の場合、確認するかどうか、型Xが適切なGetEnumeratorメソッド。Otherwise, determine whether the type X has an appropriate GetEnumerator method:

    • 型のメンバーの参照を実行X識別子を持つGetEnumeratorと型引数はありません。Perform member lookup on the type X with identifier GetEnumerator and no type arguments. メンバーの検索に一致を生成しない、または、あいまいさを生成します。 または、メソッド グループではない一致は、以下に示すは列挙可能なインターフェイスを確認します。If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. メンバー検索は何も、メソッド グループ、または一致するものを除くが生成される場合に、警告を発行することをお勧めします。It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
    • メソッドの結果として得られるグループと、空の引数リストを使用するオーバー ロードの解決を実行します。Perform overload resolution using the resulting method group and an empty argument list. 適切なメソッドのオーバー ロードの解決結果、か、あいまいな結果しますが、メソッドは、以下に示すように列挙可能なインターフェイスの静的またはパブリックではありませんのいずれかのチェックを 1 つの最適な方法で結果します。If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. オーバー ロードの解決は何も明確なパブリック インスタンス メソッドまたは適切なメソッドを除くが生成される場合に、警告を発行することをお勧めします。It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
    • 戻り値の型の場合EGetEnumeratorメソッドがクラスではない、構造体またはインターフェイス型、エラーが生成および以降の手順は実行されません。If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
    • メンバー参照がで実行されるE識別子を持つCurrentと型引数はありません。Member lookup is performed on E with the identifier Current and no type arguments. メンバー検索の一致結果は、結果は、エラーまたは結果が読み取りを許可されているパブリック インスタンス プロパティ以外のすべて、エラーが生成され、以降の手順は実行されません。If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
    • メンバー参照がで実行されるE識別子を持つMoveNextと型引数はありません。Member lookup is performed on E with the identifier MoveNext and no type arguments. メンバー検索の一致結果は、結果は、エラーに対して、または、結果は、メソッド グループ以外のすべての場合は、エラーが発生し、以降の手順は行われません。If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.
    • オーバー ロードの解決は、空の引数リストを持つメソッド グループで実行されます。Overload resolution is performed on the method group with an empty argument list. いない適用可能なメソッド、あいまいな結果または 1 つの最適な方法が、そのメソッドのオーバー ロード解決の結果は静的であるか、パブリックではありません、またはその戻り値の型でない場合boolあり、エラーが生成されるため、以降の手順は実行されません。If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.
    • コレクション型X列挙子の型E、および要素型の種類です、Currentプロパティ。The collection type is X, the enumerator type is E, and the element type is the type of the Current property.
  • それ以外の場合、列挙可能なインターフェイスを確認します。Otherwise, check for an enumerable interface:

    • すべての種類のデータの場合Tiが暗黙的に変換XIEnumerable<Ti>、一意の型があるTようにTないdynamicと他のすべてのTiが、暗黙的な変換IEnumerable<T>IEnumerable<Ti>コレクション型インターフェイスIEnumerable<T>列挙子の型インターフェイスIEnumerator<T>、および要素型Tします。If among all the types Ti for which there is an implicit conversion from X to IEnumerable<Ti>, there is a unique type T such that T is not dynamic and for all the other Ti there is an implicit conversion from IEnumerable<T> to IEnumerable<Ti>, then the collection type is the interface IEnumerable<T>, the enumerator type is the interface IEnumerator<T>, and the element type is T.
    • それ以外の場合、このような 1 つ以上の型がある場合Tエラーが発生し、以降の手順は実行されません。Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.
    • それ以外の場合からの暗黙的な変換がある場合XSystem.Collections.IEnumerable、インターフェイス、コレクション型はこのインターフェイスは、列挙子の型インターフェイスは、System.Collections.IEnumerator、および要素型objectします。Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.
    • それ以外の場合、エラーが発生し、以降の手順は実行されません。Otherwise, an error is produced and no further steps are taken.

上記の手順では、成功した場合、明確に、コレクションの型を生成C、列挙子の型Eおよび要素の型Tします。The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. フォームの foreach ステートメントA foreach statement of the form

foreach (V v in x) embedded_statement

を拡張されます。is then expanded to:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        while (e.MoveNext()) {
            V v = (V)(T)e.Current;
            embedded_statement
        }
    }
    finally {
        ... // Dispose e
    }
}

変数eに表示されるか、式にアクセスx埋め込みステートメントまたはプログラムの他のソース コード。The variable e is not visible to or accessible to the expression x or the embedded statement or any other source code of the program. 変数vは埋め込みステートメントでは読み取り専用です。The variable v is read-only in the embedded statement. 明示的な変換がない場合 (明示的な変換) からT(要素の型) にV(、 local_variable_type foreach ステートメント)、エラーが生成されますおよびそれ以上の手順は実行されません。If there is not an explicit conversion (Explicit conversions) from T (the element type) to V (the local_variable_type in the foreach statement), an error is produced and no further steps are taken. 場合x、値を持つnullSystem.NullReferenceExceptionが実行時にスローされます。If x has the value null, a System.NullReferenceException is thrown at run-time.

上記の拡張と一貫した動作であれば、パフォーマンス上の理由などの異なる方法では、特定の foreach ステートメントを実装するために実装が許可されます。An implementation is permitted to implement a given foreach-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.

配置vwhile 内でループがで発生しているすべての匿名関数がキャプチャ時に重要ですが、 embedded_statementします。The placement of v inside the while loop is important for how it is captured by any anonymous function occurring in the embedded_statement.

例:For example:

int[] values = { 7, 9, 13 };
Action f = null;

foreach (var value in values)
{
    if (f == null) f = () => Console.WriteLine("First value: " + value);
}

f();

場合vwhile の外部で宣言されたループでは、すべてのイテレーションと後に、その値の間で共有は、ループは、最終的な値になります13はどのような呼び出しf印刷します。If v was declared outside of the while loop, it would be shared among all iterations, and its value after the for loop would be the final value, 13, which is what the invocation of f would print. 代わりに、各反復処理に独自の変数があるためv、によってキャプチャされた、1 つf最初の値を保持するイテレーションは引き続き7、印刷される内容であります。Instead, because each iteration has its own variable v, the one captured by f in the first iteration will continue to hold the value 7, which is what will be printed. (注: 以前のバージョンの c# 宣言vwhile の外側のループします)。(Note: earlier versions of C# declared v outside of the while loop.)

本体、ブロックが最後に、次の手順に従って構築されます。The body of the finally block is constructed according to the following steps:

  • 暗黙的な変換がある場合ESystem.IDisposableし、インターフェイスIf there is an implicit conversion from E to the System.IDisposable interface, then

    • 場合Enull 非許容値型は、finally 句は、相当する意味的に拡張されます。If E is a non-nullable value type then the finally clause is expanded to the semantic equivalent of:

      finally {
          ((System.IDisposable)e).Dispose();
      }
      
    • それ以外の場合、finally 句は、相当する意味的に拡張されます。Otherwise the finally clause is expanded to the semantic equivalent of:

      finally {
          if (e != null) ((System.IDisposable)e).Dispose();
      }
      

    場合を除くE値の型または値の型のキャストをインスタンス化される型パラメーターは、eSystem.IDisposableが発生するボックス化は発生しません。except that if E is a value type, or a type parameter instantiated to a value type, then the cast of e to System.IDisposable will not cause boxing to occur.

  • の場合Eシールされた型である、finally 句が空のブロックに拡張されます。Otherwise, if E is a sealed type, the finally clause is expanded to an empty block:

    finally {
    }
    
  • それ以外の場合、finally 句に拡張されます。Otherwise, the finally clause is expanded to:

    finally {
        System.IDisposable d = e as System.IDisposable;
        if (d != null) d.Dispose();
    }
    

    ローカル変数dに表示されるか、ユーザーのコードからアクセスします。The local variable d is not visible to or accessible to any user code. 具体的には、競合しない他の変数がスコープに含まれると、finally ブロックします。In particular, it does not conflict with any other variable whose scope includes the finally block.

順序foreach配列の要素の走査、次に示します。1 次元配列の要素は、インデックスの昇順で走査するは、インデックスから始まって 0インデックスで終わるLength - 1します。The order in which foreach traverses the elements of an array, is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length - 1. 多次元配列は、右端の次元のインデックスが増加してから、左側に、[次へ] の左側ディメンションにするように、要素が走査されます。For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left.

次の例は、要素の順序で、2 次元の配列内の各値を印刷します。The following example prints out each value in a two-dimensional array, in element order:

using System;

class Test
{
    static void Main() {
        double[,] values = {
            {1.2, 2.3, 3.4, 4.5},
            {5.6, 6.7, 7.8, 8.9}
        };

        foreach (double elementValue in values)
            Console.Write("{0} ", elementValue);

        Console.WriteLine();
    }
}

生成される出力は次のとおりです。The output produced is as follows:

1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9

In the example

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);

n推論されますintの要素型numbersします。the type of n is inferred to be int, the element type of numbers.

ジャンプ ステートメントJump statements

ジャンプ ステートメントは、コントロールを無条件で転送します。Jump statements unconditionally transfer control.

jump_statement
    : break_statement
    | continue_statement
    | goto_statement
    | return_statement
    | throw_statement
    ;

ジャンプ ステートメントが制御を転送する場所が呼び出された、ターゲットジャンプ ステートメントの。The location to which a jump statement transfers control is called the target of the jump statement.

ジャンプ ステートメントがブロック内で発生し、そのブロックの外側、ジャンプ ステートメントの対象では、ジャンプ ステートメントと言います終了ブロックします。When a jump statement occurs within a block, and the target of that jump statement is outside that block, the jump statement is said to exit the block. ジャンプ ステートメント ブロックからコントロールを譲渡、中には、ブロックにコントロールを移動ができることはありません。While a jump statement may transfer control out of a block, it can never transfer control into a block.

介在するのかどうか、ジャンプ ステートメントの実行は複雑tryステートメント。Execution of jump statements is complicated by the presence of intervening try statements. このようながない場合は、tryジャンプ ステートメントのステートメント、無条件で転送コントロール ジャンプ ステートメントからそのターゲットにします。In the absence of such try statements, a jump statement unconditionally transfers control from the jump statement to its target. このような仲介がtryステートメントの実行がより複雑な。In the presence of such intervening try statements, execution is more complex. ジャンプ ステートメントは、1 つまたは複数が終了した場合tryのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the jump statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finallyブロックすべての介在するtryステートメントが実行されています。This process is repeated until the finally blocks of all intervening try statements have been executed.

In the example

using System;

class Test
{
    static void Main() {
        while (true) {
            try {
                try {
                    Console.WriteLine("Before break");
                    break;
                }
                finally {
                    Console.WriteLine("Innermost finally block");
                }
            }
            finally {
                Console.WriteLine("Outermost finally block");
            }
        }
        Console.WriteLine("After break");
    }
}

finallyブロックに関連付けられている 2 つtryコントロールがジャンプ ステートメントのターゲットに転送される前にステートメントが実行されます。the finally blocks associated with two try statements are executed before control is transferred to the target of the jump statement.

生成される出力は次のとおりです。The output produced is as follows:

Before break
Innermost finally block
Outermost finally block
After break

Break ステートメントThe break statement

breakステートメント終了囲む最も近いswitchwhiledofor、またはforeachステートメント。The break statement exits the nearest enclosing switch, while, do, for, or foreach statement.

break_statement
    : 'break' ';'
    ;

ターゲットをbreakステートメントは外側の終点switchwhiledofor、またはforeachステートメント。The target of a break statement is the end point of the nearest enclosing switch, while, do, for, or foreach statement. 場合、breakステートメントがで囲まれていない、 switchwhiledofor、またはforeachステートメントでは、コンパイル時エラーが発生します。If a break statement is not enclosed by a switch, while, do, for, or foreach statement, a compile-time error occurs.

ときに複数switchwhiledofor、またはforeachステートメントが、互いに入れ子になった、breakステートメントは、最も内側のステートメントにのみ適用されます。When multiple switch, while, do, for, or foreach statements are nested within each other, a break statement applies only to the innermost statement. 複数の入れ子レベルの制御を転送する、gotoステートメント (goto ステートメント) 使用する必要があります。To transfer control across multiple nesting levels, a goto statement (The goto statement) must be used.

Abreakステートメントが終了することはできません、finallyブロック (try ステートメント)。A break statement cannot exit a finally block (The try statement). ときに、breakステートメント内で発生、finallyのターゲットをブロック、breakステートメント内で同じでなければなりませんfinallyブロックは、それ以外の場合、コンパイル時エラーが発生します。When a break statement occurs within a finally block, the target of the break statement must be within the same finally block; otherwise, a compile-time error occurs.

Abreakステートメントが次のように実行されます。A break statement is executed as follows:

  • 場合、breakステートメントは、1 つまたは複数が終了したtryのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the break statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finallyブロックすべての介在するtryステートメントが実行されています。This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 対象に制御が移ります、breakステートメント。Control is transferred to the target of the break statement.

breakステートメント無条件に制御を転送他の場所での終了点をbreakステートメントが到達可能ではありません。Because a break statement unconditionally transfers control elsewhere, the end point of a break statement is never reachable.

Continue ステートメントThe continue statement

continueステートメントが最も近い外側の新しいイテレーションを開始whiledofor、またはforeachステートメント。The continue statement starts a new iteration of the nearest enclosing while, do, for, or foreach statement.

continue_statement
    : 'continue' ';'
    ;

ターゲットをcontinueステートメントは外側の埋め込みステートメントの終了点whiledofor、またはforeachステートメント。The target of a continue statement is the end point of the embedded statement of the nearest enclosing while, do, for, or foreach statement. 場合、continueステートメントがで囲まれていない、 whiledofor、またはforeachステートメントでは、コンパイル時エラーが発生します。If a continue statement is not enclosed by a while, do, for, or foreach statement, a compile-time error occurs.

ときに複数whiledofor、またはforeachステートメントが、互いに入れ子になった、continueステートメントは、最も内側のステートメントにのみ適用されます。When multiple while, do, for, or foreach statements are nested within each other, a continue statement applies only to the innermost statement. 複数の入れ子レベルの制御を転送する、gotoステートメント (goto ステートメント) 使用する必要があります。To transfer control across multiple nesting levels, a goto statement (The goto statement) must be used.

Acontinueステートメントが終了することはできません、finallyブロック (try ステートメント)。A continue statement cannot exit a finally block (The try statement). ときに、continueステートメント内で発生、finallyのターゲットをブロック、continueステートメント内で同じでなければなりませんfinallyブロックは、それ以外の場合、コンパイル時エラーが発生します。When a continue statement occurs within a finally block, the target of the continue statement must be within the same finally block; otherwise a compile-time error occurs.

Acontinueステートメントが次のように実行されます。A continue statement is executed as follows:

  • 場合、continueステートメントは、1 つまたは複数が終了したtryのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the continue statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finallyブロックすべての介在するtryステートメントが実行されています。This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 対象に制御が移ります、continueステートメント。Control is transferred to the target of the continue statement.

continueステートメント無条件に制御を転送他の場所での終了点をcontinueステートメントが到達可能ではありません。Because a continue statement unconditionally transfers control elsewhere, the end point of a continue statement is never reachable.

GoTo ステートメントThe goto statement

gotoステートメントはラベルでマークされているステートメントに制御を転送します。The goto statement transfers control to a statement that is marked by a label.

goto_statement
    : 'goto' identifier ';'
    | 'goto' 'case' constant_expression ';'
    | 'goto' 'default' ';'
    ;

ターゲットをgoto識別子ステートメントは、特定のラベルとラベル付きステートメント。The target of a goto identifier statement is the labeled statement with the given label. 現在の関数のメンバーでは、指定した名前のラベルが存在しない場合、または場合、gotoステートメントは、ラベルのスコープ内で、コンパイル時エラーが発生します。If a label with the given name does not exist in the current function member, or if the goto statement is not within the scope of the label, a compile-time error occurs. このルールの使用を許可する、gotoステートメントを入れ子になったスコープではなく、入れ子になったスコープ外の制御を転送します。This rule permits the use of a goto statement to transfer control out of a nested scope, but not into a nested scope. In the example

using System;

class Test
{
    static void Main(string[] args) {
        string[,] table = {
            {"Red", "Blue", "Green"},
            {"Monday", "Wednesday", "Friday"}
        };

        foreach (string str in args) {
            int row, colm;
            for (row = 0; row <= 1; ++row)
                for (colm = 0; colm <= 2; ++colm)
                    if (str == table[row,colm])
                         goto done;

            Console.WriteLine("{0} not found", str);
            continue;
    done:
            Console.WriteLine("Found {0} at [{1}][{2}]", str, row, colm);
        }
    }
}

gotoステートメントを使用して、入れ子になったスコープ外の制御を転送します。a goto statement is used to transfer control out of a nested scope.

ターゲットをgoto caseステートメントがステートメントの一覧で、すぐ外側switchステートメント (switch ステートメント) が含まれています、case特定の定数値を持つラベル。The target of a goto case statement is the statement list in the immediately enclosing switch statement (The switch statement), which contains a case label with the given constant value. 場合、goto caseステートメントがで囲まれていない、switchステートメントでは場合、 constant_expressionは暗黙的に変換できません (暗黙的な変換) の管理の型をそれを囲む最も近いswitchステートメントでは、場合、または最も近い外側switchステートメントを含まない、caseコンパイル時エラーが発生した特定の定数値でラベルを付けます。If the goto case statement is not enclosed by a switch statement, if the constant_expression is not implicitly convertible (Implicit conversions) to the governing type of the nearest enclosing switch statement, or if the nearest enclosing switch statement does not contain a case label with the given constant value, a compile-time error occurs.

ターゲットをgoto defaultステートメントがステートメントの一覧で、すぐ外側switchステートメント (switch ステートメント) が含まれています、defaultラベル。The target of a goto default statement is the statement list in the immediately enclosing switch statement (The switch statement), which contains a default label. 場合、goto defaultステートメントがで囲まれていない、switchステートメントでは、場合囲む最も近いswitchステートメントを含まない、defaultラベル付け、コンパイル時エラーが発生します。If the goto default statement is not enclosed by a switch statement, or if the nearest enclosing switch statement does not contain a default label, a compile-time error occurs.

Agotoステートメントが終了することはできません、finallyブロック (try ステートメント)。A goto statement cannot exit a finally block (The try statement). ときに、gotoステートメント内で発生、finallyのターゲットをブロック、gotoステートメント内で同じでなければなりませんfinallyブロック、またはそれ以外の場合、コンパイル時エラーが発生しました。When a goto statement occurs within a finally block, the target of the goto statement must be within the same finally block, or otherwise a compile-time error occurs.

Agotoステートメントが次のように実行されます。A goto statement is executed as follows:

  • 場合、gotoステートメントは、1 つまたは複数が終了したtryのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the goto statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finallyブロックすべての介在するtryステートメントが実行されています。This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 対象に制御が移ります、gotoステートメント。Control is transferred to the target of the goto statement.

gotoステートメント無条件に制御を転送他の場所での終了点をgotoステートメントが到達可能ではありません。Because a goto statement unconditionally transfers control elsewhere, the end point of a goto statement is never reachable.

Return ステートメントThe return statement

returnステートメントに制御を関数の現在の呼び出し元を返します、returnステートメントが表示されます。The return statement returns control to the current caller of the function in which the return statement appears.

return_statement
    : 'return' expression? ';'
    ;

Areturn式ステートメントは、結果の型を持つメソッドは、値を計算しない関数メンバーでのみ使用できます (メソッド本体) voidsetプロパティのアクセサーまたはインデクサー、addremoveイベント、インスタンス コンス トラクター、静的コンス トラクターまたはデストラクターのアクセサー。A return statement with no expression can be used only in a function member that does not compute a value, that is, a method with the result type (Method body) void, the set accessor of a property or indexer, the add and remove accessors of an event, an instance constructor, a static constructor, or a destructor.

Areturn式とステートメントは、void 以外の結果型を持つメソッドは、値を計算する関数のメンバーでのみ使用できます、getプロパティまたはインデクサー、またはユーザー定義演算子のアクセサー。A return statement with an expression can only be used in a function member that computes a value, that is, a method with a non-void result type, the get accessor of a property or indexer, or a user-defined operator. 暗黙的な変換 (暗黙的な変換) 含んでいる関数メンバーの戻り値の型を式の型から存在する必要があります。An implicit conversion (Implicit conversions) must exist from the type of the expression to the return type of the containing function member.

戻り値のステートメントは、匿名関数式の本文にも使用できます (匿名関数式)、どの変換がこれらの関数の存在の決定に参加します。Return statements can also be used in the body of anonymous function expressions (Anonymous function expressions), and participate in determining which conversions exist for those functions.

コンパイル時エラーには、returnに表示されるステートメントをfinallyブロック (try ステートメント)。It is a compile-time error for a return statement to appear in a finally block (The try statement).

Areturnステートメントが次のように実行されます。A return statement is executed as follows:

  • 場合、returnステートメント、式を指定する式が評価され、結果の値は、暗黙的な変換で含まれる関数の戻り値の型に変換されます。If the return statement specifies an expression, the expression is evaluated and the resulting value is converted to the return type of the containing function by an implicit conversion. 変換の結果では、関数によって生成される結果値になります。The result of the conversion becomes the result value produced by the function.
  • 場合、returnステートメントが 1 つまたは複数で囲まれたtryまたはcatchのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the return statement is enclosed by one or more try or catch blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finally外側のすべてのブロックtryステートメントが実行されています。This process is repeated until the finally blocks of all enclosing try statements have been executed.
  • 含まれる関数は、非同期関数ではありません、存在する場合、制御が、結果の値と共に含まれる関数の呼び出し元に返されます。If the containing function is not an async function, control is returned to the caller of the containing function along with the result value, if any.
  • 親関数が非同期関数で、現在の呼び出し元に制御が返されますされ、結果の値、存在する場合に記録されますタスクを返す」の説明に従って場合 (列挙子インターフェイス)。If the containing function is an async function, control is returned to the current caller, and the result value, if any, is recorded in the return task as described in (Enumerator interfaces).

returnステートメント無条件に制御を転送他の場所での終了点をreturnステートメントが到達可能ではありません。Because a return statement unconditionally transfers control elsewhere, the end point of a return statement is never reachable.

Throw ステートメントThe throw statement

throwステートメントが例外をスローします。The throw statement throws an exception.

throw_statement
    : 'throw' expression? ';'
    ;

Athrow式を持つステートメント、式を評価することによって生成された値をスローします。A throw statement with an expression throws the value produced by evaluating the expression. 式は、クラス型の値を表す必要がありますSystem.Exceptionから派生したクラス型のSystem.Exceptionまたは型パラメーターの型を持つのSystem.Exception(またはそのサブクラス)、有効な基本クラスとして。The expression must denote a value of the class type System.Exception, of a class type that derives from System.Exception or of a type parameter type that has System.Exception (or a subclass thereof) as its effective base class. 式の評価が生成される場合nullSystem.NullReferenceExceptionが代わりにスローされます。If evaluation of the expression produces null, a System.NullReferenceException is thrown instead.

Athrow式ステートメントでのみ使用できます、catchブロック、そのステートメントが再処理をしている現在の例外をスロー後者catchブロックします。A throw statement with no expression can be used only in a catch block, in which case that statement re-throws the exception that is currently being handled by that catch block.

throwステートメント無条件に制御を転送他の場所での終了点をthrowステートメントが到達可能ではありません。Because a throw statement unconditionally transfers control elsewhere, the end point of a throw statement is never reachable.

最初に制御が移りますが、例外がスローされたときにcatch句で、それを囲むtry例外を処理できるステートメント。When an exception is thrown, control is transferred to the first catch clause in an enclosing try statement that can handle the exception. 適切な例外ハンドラーに制御を転送するポイントにスローされる例外のポイントから実行されるプロセスと呼びます例外の反映します。The process that takes place from the point of the exception being thrown to the point of transferring control to a suitable exception handler is known as exception propagation. まで、次の手順を繰り返し評価するは、例外の反映、catch例外に一致する句が見つかりました。Propagation of an exception consists of repeatedly evaluating the following steps until a catch clause that matches the exception is found. この説明で、スロー ポイントで例外がスローされる場所は、最初にします。In this description, the throw point is initially the location at which the exception is thrown.

  • 現在の関数メンバーの各tryステートメントを囲むスロー ポイントが調べられます。In the current function member, each try statement that encloses the throw point is examined. 各ステートメントに対してS最も内側以降のtryステートメントと、最も外側で終了するまでtryステートメントでは、次の手順が評価されます。For each statement S, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated:

    • 場合、tryブロックSスロー ポイントを囲む S が 1 つまたは複数catch句、catch句は、適切なハンドラーに指定された規則に従って、例外を検索する外観の順序でチェックされますセクションtry ステートメントします。If the try block of S encloses the throw point and if S has one or more catch clauses, the catch clauses are examined in order of appearance to locate a suitable handler for the exception, according to the rules specified in Section The try statement. 一致する場合catch句が見つかると、そのブロックに制御を転送して例外の反映が完了したcatch句。If a matching catch clause is located, the exception propagation is completed by transferring control to the block of that catch clause.

    • の場合、tryブロックまたはcatchのブロックSスロー ポイントを囲む場合Sが、finallyに転送されるブロック、制御、finallyブロックします。Otherwise, if the try block or a catch block of S encloses the throw point and if S has a finally block, control is transferred to the finally block. 場合、finallyブロックは、別の例外をスロー、現在の例外の処理が終了します。If the finally block throws another exception, processing of the current exception is terminated. それ以外の場合、コントロールの終了ポイントに達したら、finallyブロック、現在の例外の処理が続行します。Otherwise, when control reaches the end point of the finally block, processing of the current exception is continued.

  • 例外ハンドラーが現在の関数の呼び出しでない場合は、関数の呼び出しが終了し、次のいずれか。If an exception handler was not located in the current function invocation, the function invocation is terminated, and one of the following occurs:

    • 現在の関数が非同期以外の場合は、上記の手順が、関数の呼び出し元の関数メンバーの呼び出し元のステートメントに対応するスロー ポイントに繰り返されます。If the current function is non-async, the steps above are repeated for the caller of the function with a throw point corresponding to the statement from which the function member was invoked.

    • 現在の関数は、async とタスクを返すには、例外は」の説明に従ってエラーが発生したか取り消された状態には、戻り値のタスクに記録されます。列挙子インターフェイスします。If the current function is async and task-returning, the exception is recorded in the return task, which is put into a faulted or cancelled state as described in Enumerator interfaces.

    • 現在のスレッドの同期コンテキストを通知する」の説明に従って、現在の関数が非同期と void を返す場合は、列挙可能なインターフェイスします。If the current function is async and void-returning, the synchronization context of the current thread is notified as described in Enumerable interfaces.

  • 例外の処理には、現在のスレッドですべての関数メンバーの呼び出しが終了する場合、スレッドに、例外のハンドラーがないことを示すし、スレッドが自体が終了します。If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. このような終了の影響は、実装定義です。The impact of such termination is implementation-defined.

Try ステートメントThe try statement

tryステートメント ブロックの実行中に発生する例外をキャッチするためのメカニズムを提供します。The try statement provides a mechanism for catching exceptions that occur during execution of a block. さらに、tryステートメントでは、コントロールが離れるときに常に実行されるコードのブロックを指定する機能、tryステートメント。Furthermore, the try statement provides the ability to specify a block of code that is always executed when control leaves the try statement.

try_statement
    : 'try' block catch_clause+
    | 'try' block finally_clause
    | 'try' block catch_clause+ finally_clause
    ;

catch_clause
    : 'catch' exception_specifier? exception_filter?  block
    ;

exception_specifier
    : '(' type identifier? ')'
    ;

exception_filter
    : 'when' '(' expression ')'
    ;

finally_clause
    : 'finally' block
    ;

次の 3 つの可能な形式としては、tryステートメント。There are three possible forms of try statements:

  • Atryブロックでは、1 つまたは複数続くcatchブロックします。A try block followed by one or more catch blocks.
  • Atryブロックが続く、finallyブロックします。A try block followed by a finally block.
  • Atryブロックでは、1 つまたは複数続くcatchブロックが続く、finallyブロックします。A try block followed by one or more catch blocks followed by a finally block.

ときに、catch句を指定します、 exception_specifier、型でなければなりませんSystem.Exceptionから派生した型System.Exceptionまたは型パラメーターの型を持つSystem.Exception(またはそのサブクラス)、効果的なとして基本クラスです。When a catch clause specifies an exception_specifier, the type must be System.Exception, a type that derives from System.Exception or a type parameter type that has System.Exception (or a subclass thereof) as its effective base class.

ときに、catch句では、両方を指定します、 exception_specifierで、識別子例外変数指定した名前と型の宣言します。When a catch clause specifies both an exception_specifier with an identifier, an exception variable of the given name and type is declared. 例外変数は、そのスコープでローカル変数に対応、catch句。The exception variable corresponds to a local variable with a scope that extends over the catch clause. 実行中に、 exception_filterブロック、例外変数は、現在処理中の例外を表します。During execution of the exception_filter and block, the exception variable represents the exception currently being handled. 確実な代入をチェックのために、例外変数は間違いなく全体のスコープに割り当てられていると見なされます。For purposes of definite assignment checking, the exception variable is considered definitely assigned in its entire scope.

しない限り、catch句にはで例外変数名が含まれて、フィルターで例外オブジェクトにアクセスすることはできませんとcatchブロックします。Unless a catch clause includes an exception variable name, it is impossible to access the exception object in the filter and catch block.

Acatch句が指定されていない、 exception_specifier 、一般的なと呼びますcatch句。A catch clause that does not specify an exception_specifier is called a general catch clause.

一部のプログラミング言語から派生したオブジェクトとして表現ではない例外をサポート可能性がありますSystem.Exception、c# コードで、このような例外を生成しない可能性があります。Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code. 一般的なcatchこのような例外をキャッチする句を使用することがあります。A general catch clause may be used to catch such exceptions. したがって、一般的なcatch句は、種類を指定する 1 つから意味の異なるSystem.Exception前者可能性がありますも例外をキャッチする他の言語で、します。Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages.

例外のハンドラーを見つけるためにcatch句は、構文の順序でチェックされます。In order to locate a handler for an exception, catch clauses are examined in lexical order. 場合、catch句には例外フィルターなしの型を指定します、それ以降のコンパイル時エラーがcatchで同じ句tryステートメントを入力すると、同じかから派生する型を指定します。If a catch clause specifies a type but no exception filter, it is a compile-time error for a later catch clause in the same try statement to specify a type that is the same as, or is derived from, that type. 場合、catch句型を持たないとフィルターなしを指定、最後にある必要がありますcatch句をtryステートメント。If a catch clause specifies no type and no filter, it must be the last catch clause for that try statement.

内で、catchブロック、throwステートメント (throw ステートメント) 式を指定しないと、によってキャッチされた例外を再スローに使用できる、catchブロックします。Within a catch block, a throw statement (The throw statement) with no expression can be used to re-throw the exception that was caught by the catch block. 例外変数への割り当てでは、再スローされる例外は変更されません。Assignments to an exception variable do not alter the exception that is re-thrown.

In the example

using System;

class Test
{
    static void F() {
        try {
            G();
        }
        catch (Exception e) {
            Console.WriteLine("Exception in F: " + e.Message);
            e = new Exception("F");
            throw;                // re-throw
        }
    }

    static void G() {
        throw new Exception("G");
    }

    static void Main() {
        try {
            F();
        }
        catch (Exception e) {
            Console.WriteLine("Exception in Main: " + e.Message);
        }
    }
}

メソッドF例外をキャッチ、診断情報をコンソールに出力、例外変数を変更し、例外が再度スローします。the method F catches an exception, writes some diagnostic information to the console, alters the exception variable, and re-throws the exception. 再スローされる例外には、元の例外があるため、生成される出力です。The exception that is re-thrown is the original exception, so the output produced is:

Exception in F: G
Exception in Main: G

最初の catch ブロックをスローしていた場合e現在の例外をスローするには、代わりに生成される出力は次のようになります。If the first catch block had thrown e instead of rethrowing the current exception, the output produced would be as follows:

Exception in F: G
Exception in Main: F

コンパイル時エラーには、 breakcontinue、またはgotoステートメントの制御を転送する、finallyブロックします。It is a compile-time error for a break, continue, or goto statement to transfer control out of a finally block. ときに、 breakcontinue、またはgotoでステートメントが発生した、finallyステートメントのターゲット ブロックが同じでなければなりませんfinallyブロック、またはそれ以外の場合、コンパイル時エラーが発生しました。When a break, continue, or goto statement occurs in a finally block, the target of the statement must be within the same finally block, or otherwise a compile-time error occurs.

コンパイル時エラーには、returnステートメントで発生する、finallyブロックします。It is a compile-time error for a return statement to occur in a finally block.

Atryステートメントが次のように実行されます。A try statement is executed as follows:

  • 制御が移ります、tryブロックします。Control is transferred to the try block.

  • コントロールの終了点に達すると、tryブロック。When and if control reaches the end point of the try block:

    • 場合、tryステートメントには、finallyブロック、finallyブロックが実行されます。If the try statement has a finally block, the finally block is executed.
    • 終点に制御が移ります、tryステートメント。Control is transferred to the end point of the try statement.
  • 例外が伝達される場合、tryステートメントの実行中に、tryブロック。If an exception is propagated to the try statement during execution of the try block:

    • catch句は、存在する場合、適切な例外ハンドラーを検索する外観の順序でチェックされます。The catch clauses, if any, are examined in order of appearance to locate a suitable handler for the exception. 場合、catch句は、型を指定していないまたは例外の種類または例外の種類の基本型を指定します。If a catch clause does not specify a type, or specifies the exception type or a base type of the exception type:
      • 場合、catch句例外変数を宣言して、例外オブジェクトが例外変数に割り当てられます。If the catch clause declares an exception variable, the exception object is assigned to the exception variable.
      • 場合、catch句は、例外フィルターを宣言して、フィルターが評価されます。If the catch clause declares an exception filter, the filter is evaluated. 評価されると、 falsecatch 句は、一致ではない場合、いずれかで検索を続行する後続catchの適切なハンドラー句。If it evaluates to false, the catch clause is not a match, and the search continues through any subsequent catch clauses for a suitable handler.
      • それ以外の場合、catch句は、一致と見なされ、照合に制御が移りますcatchブロックします。Otherwise, the catch clause is considered a match, and control is transferred to the matching catch block.
      • コントロールの終了点に達すると、catchブロック。When and if control reaches the end point of the catch block:
        • 場合、tryステートメントには、finallyブロック、finallyブロックが実行されます。If the try statement has a finally block, the finally block is executed.
        • 終点に制御が移ります、tryステートメント。Control is transferred to the end point of the try statement.
      • 例外が伝達される場合、tryステートメントの実行中に、catchブロック。If an exception is propagated to the try statement during execution of the catch block:
        • 場合、tryステートメントには、finallyブロック、finallyブロックが実行されます。If the try statement has a finally block, the finally block is executed.
        • [次へ] の外側に、例外が伝達されるtryステートメント。The exception is propagated to the next enclosing try statement.
    • 場合、tryステートメントが nocatch句しない場合またはcatch句に一致する例外。If the try statement has no catch clauses or if no catch clause matches the exception:
      • 場合、tryステートメントには、finallyブロック、finallyブロックが実行されます。If the try statement has a finally block, the finally block is executed.
      • [次へ] の外側に、例外が伝達されるtryステートメント。The exception is propagated to the next enclosing try statement.

ステートメントをfinallyブロックは、コントロールが離れるときに常に実行をtryステートメント。The statements of a finally block are always executed when control leaves a try statement. コントロールの転送を実行した結果として、通常の実行の結果として発生するかどうかこれは true、 breakcontinuegoto、またはreturnステートメント、または例外の反映の結果として、 tryステートメント。This is true whether the control transfer occurs as a result of normal execution, as a result of executing a break, continue, goto, or return statement, or as a result of propagating an exception out of the try statement.

実行中に例外がスローされた場合、finallyブロックし、キャッチされない例外の反映 [次へ] の外側に同じ finally ブロック内でtryステートメント。If an exception is thrown during execution of a finally block, and is not caught within the same finally block, the exception is propagated to the next enclosing try statement. 別の例外の反映中だった場合は、その例外は失われます。If another exception was in the process of being propagated, that exception is lost. 例外を伝達するプロセスについては、説明の説明にさらに、throwステートメント (throw ステートメント)。The process of propagating an exception is discussed further in the description of the throw statement (The throw statement).

tryのブロックをtryステートメントに到達できる場合、tryステートメントに到達します。The try block of a try statement is reachable if the try statement is reachable.

Acatchのブロックをtryステートメントに到達できる場合、tryステートメントに到達します。A catch block of a try statement is reachable if the try statement is reachable.

finallyのブロックをtryステートメントに到達できる場合、tryステートメントに到達します。The finally block of a try statement is reachable if the try statement is reachable.

終点をtryステートメントに到達できるは、次の両方に該当する場合。The end point of a try statement is reachable if both of the following are true:

  • 終点、tryブロックに到達できないか、末尾が少なくとも 1 つのポイントcatchブロックに到達します。The end point of the try block is reachable or the end point of at least one catch block is reachable.
  • 場合、finallyブロックが存在する場合は、終点、finallyブロックに到達します。If a finally block is present, the end point of the finally block is reachable.

Checked と unchecked ステートメントThe checked and unchecked statements

checkeduncheckedステートメントは制御を使用して、オーバーフロー チェック コンテキスト整数型の算術演算と変換します。The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

checked_statement
    : 'checked' block
    ;

unchecked_statement
    : 'unchecked' block
    ;

checkedステートメントは、すべての式、ブロックchecked コンテキストで評価されると、uncheckedステートメントは、すべての式、ブロックで評価される、unchecked コンテキスト。The checked statement causes all expressions in the block to be evaluated in a checked context, and the unchecked statement causes all expressions in the block to be evaluated in an unchecked context.

checkeduncheckedステートメントは同等では、checkedunchecked演算子 (checked と unchecked 演算子) 式ではなくブロック上で動作する点を除いて、.The checked and unchecked statements are precisely equivalent to the checked and unchecked operators (The checked and unchecked operators), except that they operate on blocks instead of expressions.

Lock ステートメントThe lock statement

lockステートメント、特定のオブジェクトの相互排他ロックが取得、ステートメントを実行、ロックを解放します。The lock statement obtains the mutual-exclusion lock for a given object, executes a statement, and then releases the lock.

lock_statement
    : 'lock' '(' expression ')' embedded_statement
    ;

式をlockステートメントがある既知の型の値を表す必要があります、 reference_typeします。The expression of a lock statement must denote a value of a type known to be a reference_type. 暗黙的なボックス化変換なし (ボックス化変換) の式が実行されるまで、lockステートメント、およびそのため、式の値を表すことのコンパイル時エラー、 value_type.No implicit boxing conversion (Boxing conversions) is ever performed for the expression of a lock statement, and thus it is a compile-time error for the expression to denote a value of a value_type.

Alock形式のステートメントA lock statement of the form

lock (x) ...

場所xの式を指定するreference_typeとまったく同じですwhere x is an expression of a reference_type, is precisely equivalent to

bool __lockWasTaken = false;
try {
    System.Threading.Monitor.Enter(x, ref __lockWasTaken);
    ...
}
finally {
    if (__lockWasTaken) System.Threading.Monitor.Exit(x);
}

ただし、x が評価されるのは 1 回だけです。except that x is only evaluated once.

相互排他ロックが保持されている間、同じ実行スレッドで実行されるコードできますも入手して、ロックを解放します。While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. ただし、他のスレッドで実行されるコードは、ロックが解放されるまで、ロックの取得からブロックされます。However, code executing in other threads is blocked from obtaining the lock until the lock is released.

ロックSystem.Type静的データへのアクセスを同期するためにオブジェクトはお勧めしません。Locking System.Type objects in order to synchronize access to static data is not recommended. 他のコードは、デッドロックが発生することができますが、同じ型にロックがあります。Other code might lock on the same type, which can result in deadlock. プライベート静的オブジェクトをロックして静的なデータへのアクセスを同期することをお勧めします。A better approach is to synchronize access to static data by locking a private static object. 例:For example:

class Cache
{
    private static readonly object synchronizationObject = new object();

    public static void Add(object x) {
        lock (Cache.synchronizationObject) {
            ...
        }
    }

    public static void Remove(object x) {
        lock (Cache.synchronizationObject) {
            ...
        }
    }
}

using ステートメントThe using statement

usingステートメントが 1 つまたは複数のリソースを取得し、ステートメントを実行およびリソースを破棄します。The using statement obtains one or more resources, executes a statement, and then disposes of the resource.

using_statement
    : 'using' '(' resource_acquisition ')' embedded_statement
    ;

resource_acquisition
    : local_variable_declaration
    | expression
    ;

Aリソースクラスまたは構造体を実装するSystem.IDisposable、という名前の 1 つのパラメーターなしのメソッドを含むDisposeします。A resource is a class or struct that implements System.IDisposable, which includes a single parameterless method named Dispose. リソースを使用してコードを呼び出すことができますDisposeをリソースが不要になったことを示します。Code that is using a resource can call Dispose to indicate that the resource is no longer needed. 場合Disposeは呼び出されません、ガベージ コレクションの結果として自動的に破棄が最終的が発生します。If Dispose is not called, then automatic disposal eventually occurs as a consequence of garbage collection.

場合のフォームresource_acquisitionlocal_variable_declarationの型、 local_variable_declarationいずれかである必要がありますdynamicまたは型暗黙的に変換できるSystem.IDisposableします。If the form of resource_acquisition is local_variable_declaration then the type of the local_variable_declaration must be either dynamic or a type that can be implicitly converted to System.IDisposable. 場合のフォームresource_acquisitionこの式は、暗黙的に変換可能である必要がありますし、System.IDisposableします。If the form of resource_acquisition is expression then this expression must be implicitly convertible to System.IDisposable.

宣言されたローカル変数、 resource_acquisitionは読み取り専用であり、初期化子を含める必要があります。Local variables declared in a resource_acquisition are read-only, and must include an initializer. コンパイル時エラーが発生する場合は、埋め込みステートメントが、これらのローカル変数を変更しようとしています。 (割り当てまたは++--演算子)、それらのアドレスを取得またはとして渡したりrefまたはoutパラメーター。A compile-time error occurs if the embedded statement attempts to modify these local variables (via assignment or the ++ and -- operators) , take the address of them, or pass them as ref or out parameters.

Ausingステートメントは 3 つの部分に変換されます。 取得、使用状況、および破棄します。A using statement is translated into three parts: acquisition, usage, and disposal. リソースの使用量が暗黙的にで囲まれている、tryステートメントを含む、finally句。Usage of the resource is implicitly enclosed in a try statement that includes a finally clause. これは、finally句は、リソースを破棄します。This finally clause disposes of the resource. 場合、nullのリソースを取得すると、なしの呼び出しをDisposeが行われると例外はスローされません。If a null resource is acquired, then no call to Dispose is made, and no exception is thrown. 型の場合は、リソースdynamic動的の暗黙的な変換を動的に変換されます (動的の暗黙的な変換) にIDisposable変換があることを確認するには取得中に使用および破棄する前に成功します。If the resource is of type dynamic it is dynamically converted through an implicit dynamic conversion (Implicit dynamic conversions) to IDisposable during acquisition in order to ensure that the conversion is successful before the usage and disposal.

Ausing形式のステートメントA using statement of the form

using (ResourceType resource = expression) statement

次の 3 つの可能な展開のいずれかに対応します。corresponds to one of three possible expansions. ときにResourceTypenull 非許容値型では、拡張が、When ResourceType is a non-nullable value type, the expansion is

{
    ResourceType resource = expression;
    try {
        statement;
    }
    finally {
        ((IDisposable)resource).Dispose();
    }
}

それ以外の場合、whenResourceTypeが null 許容値型または参照型以外のdynamic、拡張Otherwise, when ResourceType is a nullable value type or a reference type other than dynamic, the expansion is

{
    ResourceType resource = expression;
    try {
        statement;
    }
    finally {
        if (resource != null) ((IDisposable)resource).Dispose();
    }
}

それ以外の場合、whenResourceTypedynamic拡張が、Otherwise, when ResourceType is dynamic, the expansion is

{
    ResourceType resource = expression;
    IDisposable d = (IDisposable)resource;
    try {
        statement;
    }
    finally {
        if (d != null) d.Dispose();
    }
}

どちらの展開、resource変数には、埋め込みのステートメントでは、読み取り専用とd変数で、アクセス不可能と非表示は、埋め込みステートメントにします。In either expansion, the resource variable is read-only in the embedded statement, and the d variable is inaccessible in, and invisible to, the embedded statement.

上記の拡張と一貫した動作であれば、パフォーマンス上の理由などの異なる方法では、特定の using ステートメントを実装するために実装が許可されます。An implementation is permitted to implement a given using-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.

Ausing形式のステートメントA using statement of the form

using (expression) statement

同じ 3 つの可能な拡張があります。has the same three possible expansions. ここでResourceTypeのコンパイル時の型を暗黙的には、expressionがあるいずれかの場合。In this case ResourceType is implicitly the compile-time type of the expression, if it has one. それ以外の場合、インターフェイスIDisposable自体として提供される、ResourceTypeします。Otherwise the interface IDisposable itself is used as the ResourceType. resource変数で、アクセス不可能と非表示は、埋め込みステートメントにします。The resource variable is inaccessible in, and invisible to, the embedded statement.

ときに、 resource_acquisitionの形式をlocal_variable_declaration、指定された型の複数のリソースを取得することができます。When a resource_acquisition takes the form of a local_variable_declaration, it is possible to acquire multiple resources of a given type. Ausing形式のステートメントA using statement of the form

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement

シーケンスに正確に同等の入れ子になってusingステートメント。is precisely equivalent to a sequence of nested using statements:

using (ResourceType r1 = e1)
    using (ResourceType r2 = e2)
        ...
            using (ResourceType rN = eN)
                statement

次の例は、という名前のファイルを作成します。log.txtし、ファイルに 2 行のテキストを書き込みます。The example below creates a file named log.txt and writes two lines of text to the file. 読み取り用にその同じファイルを開きし、コンソールに含まれている行のテキストをコピーします。The example then opens that same file for reading and copies the contained lines of text to the console.

using System;
using System.IO;

class Test
{
    static void Main() {
        using (TextWriter w = File.CreateText("log.txt")) {
            w.WriteLine("This is line one");
            w.WriteLine("This is line two");
        }

        using (TextReader r = File.OpenText("log.txt")) {
            string s;
            while ((s = r.ReadLine()) != null) {
                Console.WriteLine(s);
            }

        }
    }
}

以降、TextWriterTextReaderクラスで実装、IDisposable例を使用できるインターフェイス、usingステートメントを基になるファイルを次の書き込み正しく閉じることを確認または読み取り操作。Since the TextWriter and TextReader classes implement the IDisposable interface, the example can use using statements to ensure that the underlying file is properly closed following the write or read operations.

Yield ステートメントThe yield statement

yield反復子ブロックでは、ステートメントを使用してください (ブロック)、列挙子オブジェクトに値を生成する (列挙子オブジェクト) または列挙可能なオブジェクト (の列挙可能なオブジェクト。)反復子のまたはイテレーションの終了を通知します。The yield statement is used in an iterator block (Blocks) to yield a value to the enumerator object (Enumerator objects) or enumerable object (Enumerable objects) of an iterator or to signal the end of the iteration.

yield_statement
    : 'yield' 'return' expression ';'
    | 'yield' 'break' ';'
    ;

yield 予約語です。直前に使用する場合にのみ、特別な意味をreturnまたはbreakキーワード。yield is not a reserved word; it has special meaning only when used immediately before a return or break keyword. 他のコンテキストでyield識別子として使用できます。In other contexts, yield can be used as an identifier.

いくつかの制限がある場所について、yield次」の説明に従って、ステートメントを表示できます。There are several restrictions on where a yield statement can appear, as described in the following.

  • コンパイル時エラーには、 yield (いずれかの形式) のステートメントの外側に表示する、 method_bodyoperator_bodyまたはaccessor_bodyIt is a compile-time error for a yield statement (of either form) to appear outside a method_body, operator_body or accessor_body
  • コンパイル時エラーには、 yield (のいずれかの形式) ステートメント、匿名関数内に表示します。It is a compile-time error for a yield statement (of either form) to appear inside an anonymous function.
  • コンパイル時エラーには、 yield (いずれかの形式) のステートメントに表示される、finallyの句、tryステートメント。It is a compile-time error for a yield statement (of either form) to appear in the finally clause of a try statement.
  • コンパイル時エラーには、yield returnどこにでも表示するステートメントをtryステートメントを含むcatch句。It is a compile-time error for a yield return statement to appear anywhere in a try statement that contains any catch clauses.

次の例のいくつかの有効および無効な使用yieldステートメント。The following example shows some valid and invalid uses of yield statements.

delegate IEnumerable<int> D();

IEnumerator<int> GetEnumerator() {
    try {
        yield return 1;        // Ok
        yield break;           // Ok
    }
    finally {
        yield return 2;        // Error, yield in finally
        yield break;           // Error, yield in finally
    }

    try {
        yield return 3;        // Error, yield return in try...catch
        yield break;           // Ok
    }
    catch {
        yield return 4;        // Error, yield return in try...catch
        yield break;           // Ok
    }

    D d = delegate { 
        yield return 5;        // Error, yield in an anonymous function
    }; 
}

int MyMethod() {
    yield return 1;            // Error, wrong return type for an iterator block
}

暗黙的な変換 (暗黙的な変換) 内の式の型から存在する必要があります、 yield return yield 型ステートメント (型を生成) 反復子の。An implicit conversion (Implicit conversions) must exist from the type of the expression in the yield return statement to the yield type (Yield type) of the iterator.

Ayield returnステートメントが次のように実行されます。A yield return statement is executed as follows:

  • ステートメントで指定された式が評価、暗黙的に、yield 型に変換されに割り当てられている、Current列挙子オブジェクトのプロパティ。The expression given in the statement is evaluated, implicitly converted to the yield type, and assigned to the Current property of the enumerator object.
  • 反復子ブロックの実行が中断されます。Execution of the iterator block is suspended. 場合、yield return内で 1 つまたは複数のステートメントがtryブロック、関連付けられているfinallyブロックは、この時点では実行されません。If the yield return statement is within one or more try blocks, the associated finally blocks are not executed at this time.
  • MoveNext列挙子オブジェクトのメソッドを返しますtrue列挙子オブジェクトは、次の項目に正常に進んだことを示す、呼び出し元にします。The MoveNext method of the enumerator object returns true to its caller, indicating that the enumerator object successfully advanced to the next item.

次の列挙子オブジェクトの呼び出しMoveNextメソッドは、前回中断された場所からの反復子ブロックの実行を再開します。The next call to the enumerator object's MoveNext method resumes execution of the iterator block from where it was last suspended.

Ayield breakステートメントが次のように実行されます。A yield break statement is executed as follows:

  • 場合、yield breakステートメントが 1 つまたは複数で囲まれたtryのブロックに関連付けられているfinally、コントロール ブロックが最初に転送、finally最も内側のブロックtryステートメント。If the yield break statement is enclosed by one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. コントロールの終了点に達すると、finallyに転送されるブロック、制御、 finally [次へ] を囲むブロックtryステートメント。When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. までこのプロセスが繰り返されます、finally外側のすべてのブロックtryステートメントが実行されています。This process is repeated until the finally blocks of all enclosing try statements have been executed.
  • コントロールは、反復子ブロックの呼び出し元に返されます。Control is returned to the caller of the iterator block. いずれかになります、MoveNextメソッドまたはDispose列挙子オブジェクトのメソッド。This is either the MoveNext method or Dispose method of the enumerator object.

yield breakステートメント無条件に制御を転送他の場所での終了点をyield breakステートメントが到達可能ではありません。Because a yield break statement unconditionally transfers control elsewhere, the end point of a yield break statement is never reachable.