ステートメント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
ステートメントが 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. 定数式がコンパイル時に評価され、値が生成されると、 false
Console.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 firstConsole.WriteLine
expression statement is reachable because the block of theF
method is reachable. - 最初の式ステートメントの終点に到達できるのは、
Console.WriteLine
そのステートメントに到達可能であるためです。The end point of the firstConsole.WriteLine
expression statement is reachable because that statement is reachable. if
最初の式ステートメントの終点に到達可能であるため、ステートメントに到達Console.WriteLine
できます。Theif
statement is reachable because the end point of the firstConsole.WriteLine
expression statement is reachable.Console.WriteLine
ステートメントのブール式にif
定数値が指定されていないため、2番目の式ステートメントに到達できfalse
ます。The secondConsole.WriteLine
expression statement is reachable because the boolean expression of theif
statement does not have the constant valuefalse
.
ステートメントのエンドポイントが到達可能になるには、コンパイル時にエラーが発生するという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 theswitch
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 abreak
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 areturn
statement is missing.
BlocksBlocks
"ブロック" を使用すると、1 つのステートメントしか使用できないコンテキストで複数のステートメントを記述できます。A block permits multiple statements to be written in contexts where a single statement is allowed.
block
: '{' statement_list? '}'
;
ブロック は、かっこで囲まれた省略可能な 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.
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 areturn
statement to appear in an iterator block (butyield 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
*ステートメントリスト _ は、1つまたは複数のステートメントで構成されています。A *statement list _ consists of one or more statements written in sequence. ステートメントリストは _block * s (ブロック) および switch_block s (switch ステートメント) で発生します。Statement lists occur in _block*s (Blocks) and in switch_block s (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.
次のいずれかの条件に該当する場合は、ステートメントリスト内のステートメントに到達できます。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 reachablegoto
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.
空のステートメントは、本文が null のステートメントを記述するときに使用でき 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
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
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
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_declaration の local_variable_type は、宣言によって導入される変数の型を直接指定するか、または、 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_declarator のリストが続き、それぞれに新しい変数が導入されています。The type is followed by a list of local_variable_declarator s, each of which introduces a new variable. 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_declarator s.
- 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.
複数の変数を宣言するローカル変数宣言は、同じ型の単一の変数の複数の宣言と同じです。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
1つ以上のローカル定数を宣言 local_constant_declaration 。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_declarator のリストが続き、それぞれに新しい定数が導入されています。The type is followed by a list of constant_declarator s, each of which introduces a new constant. 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 + y
x == 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
選択ステートメントでは、いくつかの式の値に基づいて、実行に使用できるステートメントをいくつか選択します。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 yieldstrue
, 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 theif
statement. - ブール式がを生成し、
false
else
パーツが存在する場合、制御は2番目の埋め込みステートメントに転送されます。If the boolean expression yieldsfalse
and if anelse
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 theif
statement. - ブール式がを生成し、
false
else
パーツが存在しない場合、制御はステートメントの終了点に移りif
ます。If the boolean expression yieldsfalse
and if anelse
part is not present, control is transferred to the end point of theif
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
.
ステートメント if
if
が到達可能で、ブール式が定数値を持たない場合は、ステートメントの2番目の埋め込みステートメント (存在する場合) に到達 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
ステートメントが到達可能で、ブール式が定数値を持たない場合は、部分を持たないステートメントの終点に到達でき true
ます。In 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' ':'
;
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_section で構成されます。The switch_block consists of zero or more switch_section s, enclosed in braces. 各 switch_section は、1つ以上の switch_label s の後に statement_list (ステートメントリスト) が続きます。Each switch_section consists of one or more switch_label s followed by a statement_list (Statement lists).
ステートメントの 管理型 switch
は、switch 式によって設定されます。The governing type of a switch
statement is established by the switch expression.
- スイッチ式の型が、、、、、、、、、、、enum_type またはのいずれかである場合、または、
sbyte
byte
short
ushort
int
uint
long
ulong
bool
char
string
これらの型のいずれかに対応する null 許容型の場合は、それがステートメントの管理型になりswitch
ます。If the type of the switch expression issbyte
,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 theswitch
statement. - それ以外の場合、ユーザー定義の暗黙的な変換 (ユーザー定義の変換) は、switch 式の型から、、、、、、、、、、またはのいずれかの型に
sbyte
byte
対応するshort
ushort
int
uint
long
ulong
char
string
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. - それ以外の場合、このような暗黙的な変換が存在しない場合、または複数の暗黙的な変換が存在する場合は、コンパイル時エラーが発生します。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. case
同じステートメント内の2つ以上のラベルで switch
同じ定数値が指定されている場合、コンパイル時エラーが発生します。A compile-time error occurs if two or more case
labels in the same switch
statement specify the same constant value.
Switch ステートメントには、最大で1つのラベルを設定でき default
ます。There can be at most one default
label in a switch statement.
switch
ステートメントは次のように実行されます。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 acase
label in the sameswitch
statement is equal to the value of the switch expression, control is transferred to the statement list following the matchedcase
label. - 同じステートメントのラベルに指定された定数
case
switch
が switch 式の値と等しい場合、ラベルが存在する場合は、default
ラベルの後のステートメントリストに制御が移りdefault
ます。If none of the constants specified incase
labels in the sameswitch
statement is equal to the value of the switch expression, and if adefault
label is present, control is transferred to the statement list following thedefault
label. - 同じステートメントのラベルに指定されている定数
case
switch
が switch 式の値と等しい場合、default
ラベルが存在しない場合、制御はステートメントのエンドポイントに転送されswitch
ます。If none of the constants specified incase
labels in the sameswitch
statement is equal to the value of the switch expression, and if nodefault
label is present, control is transferred to the end point of theswitch
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 セクションの実行後に別の 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 セクションのステートメントの一覧は、通常、、 break
goto 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 式の文字列がラベル定数と完全に一致する場合にのみ、指定された 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
、値 null
は case ラベル定数として許可されます。When the governing type of a switch
statement is string
, the value null
is permitted as a case label constant.
Switch_block の statement_list s には、宣言ステートメント (宣言ステートメント) を含めることができます。The statement_list s 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 セクションのステートメントリストに到達できます。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:
- スイッチ式は、非定数値です。The switch expression is a non-constant value.
- Switch 式は、switch セクションのラベルに一致する定数値です
case
。The switch expression is a constant value that matches acase
label in the switch section. - スイッチ式がどのラベルとも一致しない定数値です
case
。 switch セクションにはラベルが含まれていdefault
ます。The switch expression is a constant value that doesn't match anycase
label, and the switch section contains thedefault
label. - Switch セクションのスイッチラベルが、到達可能なまたはステートメントによって参照されてい
goto case
goto default
ます。A switch label of the switch section is referenced by a reachablegoto case
orgoto default
statement.
switch
次のいずれかの条件に該当する場合は、ステートメントの終了位置に到達できます。The end point of a switch
statement is reachable if at least one of the following is true:
- ステートメントには、
switch
ステートメントを終了する到達可能なステートメントが含まれていbreak
switch
ます。Theswitch
statement contains a reachablebreak
statement that exits theswitch
statement. switch
ステートメントが到達可能で、スイッチ式が非定数値であり、default
ラベルが存在しません。Theswitch
statement is reachable, the switch expression is a non-constant value, and nodefault
label is present.- ステートメントに到達できます
switch
。 switch 式は、どのラベルにも一致しない定数値ですcase
default
。ラベルは存在しません。Theswitch
statement is reachable, the switch expression is a constant value that doesn't match anycase
label, and nodefault
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
;
while
ステートメントは次のように実行されます。A while
statement is executed as follows:
- Boolean_expression (ブール式) が評価されます。The boolean_expression (Boolean expressions) is evaluated.
- ブール式がの場合
true
、コントロールは埋め込みステートメントに転送されます。If the boolean expression yieldstrue
, 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 acontinue
statement), control is transferred to the beginning of thewhile
statement. - ブール式がの場合
false
、制御はステートメントの終了点に移りwhile
ます。If the boolean expression yieldsfalse
, control is transferred to the end point of thewhile
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
次のいずれかの条件に該当する場合は、ステートメントの終了位置に到達できます。The end point of a while
statement is reachable if at least one of the following is true:
- ステートメントには、
while
ステートメントを終了する到達可能なステートメントが含まれていbreak
while
ます。Thewhile
statement contains a reachablebreak
statement that exits thewhile
statement. while
ステートメントが到達可能で、ブール式に定数値がありませんtrue
。Thewhile
statement is reachable and the boolean expression does not have the constant valuetrue
.
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 ')' ';'
;
do
ステートメントは次のように実行されます。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 acontinue
statement), the boolean_expression (Boolean expressions) is evaluated. ブール式がの場合true
、制御はステートメントの先頭に移りdo
ます。If the boolean expression yieldstrue
, control is transferred to the beginning of thedo
statement. それ以外の場合、制御はステートメントのエンドポイントに転送されdo
ます。Otherwise, control is transferred to the end point of thedo
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
次のいずれかの条件に該当する場合は、ステートメントの終了位置に到達できます。The end point of a do
statement is reachable if at least one of the following is true:
- ステートメントには、
do
ステートメントを終了する到達可能なステートメントが含まれていbreak
do
ます。Thedo
statement contains a reachablebreak
statement that exits thedo
statement. - 埋め込みステートメントの終点に到達でき、ブール式に定数値が指定されていません
true
。The end point of the embedded statement is reachable and the boolean expression does not have the constant valuetrue
.
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_expression s (式ステートメント) のリストで構成されます。The for_initializer, if present, consists of either a local_variable_declaration (Local variable declarations) or a list of statement_expression s (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_condition と for_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_expression s (式ステートメント) のリストで構成されます。The for_iterator, if present, consists of a list of statement_expression s (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. このステップは1回だけ実行されます。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 yieldstrue
, 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 acontinue
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 yieldsfalse
, control is transferred to the end point of thefor
statement.
ステートメントの埋め込みステートメント内では for
、ステートメント break
(break ステートメント) を使用して、ステートメントのエンドポイントに制御を移す for
(したがって、埋め込みステートメントの反復処理を終了する) ことができます。また、ステートメント continue
(continue ステートメント) を使用して、埋め込みステートメントのエンドポイントに制御を移すことができます (したがって、 for_iterator を実行し、ステートメントの別の繰り返しを実行し for_condition for
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
到達できます。The embedded statement of a for
statement is reachable if one of the following is true:
for
ステートメントに到達可能で、 for_condition が存在しません。Thefor
statement is reachable and no for_condition is present.for
ステートメントに到達可能で、 for_condition が存在し、定数値がありませんfalse
。Thefor
statement is reachable and a for_condition is present and does not have the constant valuefalse
.
for
次のいずれかの条件に該当する場合は、ステートメントの終了位置に到達できます。The end point of a for
statement is reachable if at least one of the following is true:
- ステートメントには、
for
ステートメントを終了する到達可能なステートメントが含まれていbreak
for
ます。Thefor
statement contains a reachablebreak
statement that exits thefor
statement. for
ステートメントに到達可能で、 for_condition が存在し、定数値がありませんtrue
。Thefor
statement is reachable and a for_condition is present and does not have the constant valuetrue
.
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.
以下では、を簡潔にするために、、 IEnumerable
IEnumerator
、 IEnumerable<T>
および IEnumerator<T>
は、名前空間との対応する型を参照して System.Collections
System.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
式 の型が配列型である場合は、からインターフェイスへの暗黙の参照変換が行われX
IEnumerable
ます (以降はSystem.Array
このインターフェイスが実装されます)。If the typeX
of expression is an array type then there is an implicit reference conversion fromX
to theIEnumerable
interface (sinceSystem.Array
implements this interface). コレクション型 _ はインターフェイス、IEnumerable
_列挙子型_ はIEnumerator
インターフェイス、_ 要素型 は配列型の要素型X
です。The collection type _ is theIEnumerable
interface, the _enumerator type_ is theIEnumerator
interface and the _ element type is the element type of the array typeX
.式の型がの場合は、
X
dynamic
式 からインターフェイスへの暗黙的な変換IEnumerable
(暗黙の動的変換) が存在します。If the typeX
of expression isdynamic
then there is an implicit conversion from expression to theIEnumerable
interface (Implicit dynamic conversions). コレクション型 _ はインターフェイスで、IEnumerable
_列挙子の型*_ はIEnumerator
インターフェイスです。The collection type _ is theIEnumerable
interface and the _enumerator type*_ is theIEnumerator
interface.var
識別子が _local_variable_type * として指定されている場合、要素の型 はですdynamic
。それ以外の場合は、になりobject
ます。If thevar
identifier is given as the _local_variable_type* then the element type isdynamic
, otherwise it isobject
.それ以外の場合は、型に適切なメソッドがあるかどうかを確認し
X
GetEnumerator
ます。Otherwise, determine whether the typeX
has an appropriateGetEnumerator
method:- 識別子を使用して型引数を指定せずに、型に対してメンバーの参照を実行
X
GetEnumerator
します。Perform member lookup on the typeX
with identifierGetEnumerator
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.
- メソッドの戻り値の型
E
GetEnumerator
がクラス、構造体、またはインターフェイス型ではない場合は、エラーが生成され、それ以上の手順は実行されません。If the return typeE
of theGetEnumerator
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 onE
with the identifierCurrent
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 onE
with the identifierMoveNext
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 notbool
, an error is produced and no further steps are taken. - コレクション型 _ は
X
で、 _列挙子の型_ はで、E
_ 要素型 はプロパティの型ですCurrent
。The collection type _ isX
, the _enumerator type_ isE
, and the _ element type is the type of theCurrent
property.
- 識別子を使用して型引数を指定せずに、型に対してメンバーの参照を実行
それ以外の場合は、列挙可能なインターフェイスがあるかどうかを確認します。Otherwise, check for an enumerable interface:
- からへの暗黙の型変換が行われているすべての型の中
Ti
X
IEnumerable<Ti>
で、T
がでT
はなく、からへの暗黙の型変換がある場合、dynamic
Ti
IEnumerable<T>
IEnumerable<Ti>
コレクション型 _ はインターフェイス、IEnumerable<T>
_列挙子型_ はインターフェイス、IEnumerator<T>
_ 要素型 はT
です。 * はです。If among all the typesTi
for which there is an implicit conversion fromX
toIEnumerable<Ti>
, there is a unique typeT
such thatT
is notdynamic
and for all the otherTi
there is an implicit conversion fromIEnumerable<T>
toIEnumerable<Ti>
, then the collection type _ is the interfaceIEnumerable<T>
, the _enumerator type_ is the interfaceIEnumerator<T>
, and the _ element type isT
. - それ以外の場合、このような型が複数存在
T
すると、エラーが生成され、それ以上の手順は実行されません。Otherwise, if there is more than one such typeT
, then an error is produced and no further steps are taken. - それ以外の場合、からインターフェイスへの暗黙的な変換がある場合、
X
System.Collections.IEnumerable
コレクション型 _ はこのインターフェイス、 _列挙子型_ はインターフェイス、System.Collections.IEnumerator
_ 要素型 はobject
です。Otherwise, if there is an implicit conversion fromX
to theSystem.Collections.IEnumerable
interface, then the collection type _ is this interface, the _enumerator type_ is the interfaceSystem.Collections.IEnumerator
, and the _ element type isobject
. - それ以外の場合は、エラーが生成され、それ以上の手順は実行されません。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. (要素型) から (foreach ステートメントの local_variable_type) への明示的な変換 (明示的な変換) がない場合は T
V
、エラーが生成され、それ以上の手順は実行されません。 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
null
System.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.
While ループ内のの配置は v
、 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();
v
が while ループの外側で宣言されている場合、すべてのイテレーション間で共有され、for ループの後の値が最終的な値になり 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
最初のイテレーションでによってキャプチャされた値は、 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# の以前のバージョンは v
、while ループの外側で宣言されています)。(Note: earlier versions of C# declared v
outside of the while loop.)
Finally ブロックの本体は、次の手順に従って構築されます。The body of the finally block is constructed according to the following steps:
からインターフェイスへの暗黙的な変換がある場合は
E
System.IDisposable
、If there is an implicit conversion fromE
to theSystem.IDisposable
interface, thenE
が null 非許容の値型である場合、finally 句は次のようなセマンティックに拡張されます。IfE
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
が値型の場合、または値型にインスタンス化された型パラメーターの場合、へのキャストによってボックス化が発生することe
System.IDisposable
はありません。except that ifE
is a value type, or a type parameter instantiated to a value type, then the cast ofe
toSystem.IDisposable
will not cause boxing to occur.それ以外の場合、
E
が sealed 型の場合、finally 句は空のブロックに展開されます。Otherwise, ifE
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 variabled
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
最も近い switch
、、 while
do
、 for
、またはステートメントを終了し foreach
ます。The break
statement exits the nearest enclosing switch
, while
, do
, for
, or foreach
statement.
break_statement
: 'break' ';'
;
ステートメントのターゲット break
は、最も近い外側の、、 switch
while
do
、 for
、または foreach
ステートメントの終点です。The target of a break
statement is the end point of the nearest enclosing switch
, while
, do
, for
, or foreach
statement. break
ステートメントが、、、、またはステートメントで囲まれていない場合 switch
while
do
for
foreach
、コンパイル時エラーが発生します。If a break
statement is not enclosed by a switch
, while
, do
, for
, or foreach
statement, a compile-time error occurs.
複数の switch
、、、 while
do
for
、または 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.
break
ステートメントでブロックを終了することはできません 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.
break
ステートメントは次のように実行されます。A break
statement is executed as follows:
- ステートメントが、
break
関連付けられたブロックを持つ1つ以上のブロックを終了した場合try
finally
、最初にコントロールがfinally
最も内側のステートメントのブロックに転送されtry
ます。If thebreak
statement exits one or moretry
blocks with associatedfinally
blocks, control is initially transferred to thefinally
block of the innermosttry
statement. コントロールがブロックの終点に到達した場合finally
、コントロールはfinally
次の外側のステートメントのブロックに転送されtry
ます。When and if control reaches the end point of afinally
block, control is transferred to thefinally
block of the next enclosingtry
statement. このプロセスは、finally
すべてのステートメントのブロックが実行されるまで繰り返されtry
ます。This process is repeated until thefinally
blocks of all interveningtry
statements have been executed. - 制御は、ステートメントのターゲットに転送され
break
ます。Control is transferred to the target of thebreak
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
最も近い、、 while
do
for
、またはステートメントの新しい反復処理を開始し foreach
ます。The continue
statement starts a new iteration of the nearest enclosing while
, do
, for
, or foreach
statement.
continue_statement
: 'continue' ';'
;
ステートメントの対象 continue
は、最も近い外側の while
、、 do
for
、または 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
ステートメントが、、、またはステートメントで囲まれていない場合 while
do
for
foreach
、コンパイル時エラーが発生します。If a continue
statement is not enclosed by a while
, do
, for
, or foreach
statement, a compile-time error occurs.
複数の while
、 do
、 for
、または 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.
continue
ステートメントでブロックを終了することはできません 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.
continue
ステートメントは次のように実行されます。A continue
statement is executed as follows:
- ステートメントが、
continue
関連付けられたブロックを持つ1つ以上のブロックを終了した場合try
finally
、最初にコントロールがfinally
最も内側のステートメントのブロックに転送されtry
ます。If thecontinue
statement exits one or moretry
blocks with associatedfinally
blocks, control is initially transferred to thefinally
block of the innermosttry
statement. コントロールがブロックの終点に到達した場合finally
、コントロールはfinally
次の外側のステートメントのブロックに転送されtry
ます。When and if control reaches the end point of afinally
block, control is transferred to thefinally
block of the next enclosingtry
statement. このプロセスは、finally
すべてのステートメントのブロックが実行されるまで繰り返されtry
ます。This process is repeated until thefinally
blocks of all interveningtry
statements have been executed. - 制御は、ステートメントのターゲットに転送され
continue
ます。Control is transferred to the target of thecontinue
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.
goto
ステートメントでブロックを終了することはできません 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.
goto
ステートメントは次のように実行されます。A goto
statement is executed as follows:
- ステートメントが、
goto
関連付けられたブロックを持つ1つ以上のブロックを終了した場合try
finally
、最初にコントロールがfinally
最も内側のステートメントのブロックに転送されtry
ます。If thegoto
statement exits one or moretry
blocks with associatedfinally
blocks, control is initially transferred to thefinally
block of the innermosttry
statement. コントロールがブロックの終点に到達した場合finally
、コントロールはfinally
次の外側のステートメントのブロックに転送されtry
ます。When and if control reaches the end point of afinally
block, control is transferred to thefinally
block of the next enclosingtry
statement. このプロセスは、finally
すべてのステートメントのブロックが実行されるまで繰り返されtry
ます。This process is repeated until thefinally
blocks of all interveningtry
statements have been executed. - 制御は、ステートメントのターゲットに転送され
goto
ます。Control is transferred to the target of thegoto
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? ';'
;
式が指定されていないステートメントは、 return
値を計算しない関数メンバーでのみ使用できます。つまり、結果の型 (メソッド本体) を持つメソッド、 void
set
プロパティまたはインデクサーのアクセサー add
、 remove
イベントのおよびアクセサー、インスタンスコンストラクター、静的コンストラクター、またはデストラクターが使用されます。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.
return
式を持つステートメントは、値を計算する関数メンバー、つまり、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 ステートメントは、匿名関数式 (匿名関数式) の本体で使用することもできます。また、これらの関数にどの変換が存在するかを判断するためにも使用できます。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).
return
ステートメントは次のように実行されます。A return
statement is executed as follows:
- ステートメントが式を指定した場合
return
、式が評価され、結果の値は暗黙的な変換によって、含んでいる関数の戻り値の型に変換されます。If thereturn
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 thereturn
statement is enclosed by one or moretry
orcatch
blocks with associatedfinally
blocks, control is initially transferred to thefinally
block of the innermosttry
statement. コントロールがブロックの終点に到達した場合finally
、コントロールはfinally
次の外側のステートメントのブロックに転送されtry
ます。When and if control reaches the end point of afinally
block, control is transferred to thefinally
block of the next enclosingtry
statement. このプロセスは、finally
外側のすべてのステートメントのブロックが実行されるまで繰り返されtry
ます。This process is repeated until thefinally
blocks of all enclosingtry
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? ';'
;
式を含むステートメントでは、 throw
式を評価することによって生成される値がスローされます。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. 式の評価によって null
が生成 System.NullReferenceException
される場合は、代わりにがスローされます。If evaluation of the expression produces null
, a System.NullReferenceException
is thrown instead.
式が指定され throw
ていないステートメントは、ブロック内でのみ使用できます 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. この説明では、 throw point* は最初に例外がスローされる場所です。In this description, the _ throw point* is initially the location at which the exception is thrown.
現在の関数メンバーでは、
try
スローポイントを囲む各ステートメントが検査されます。In the current function member, eachtry
statement that encloses the throw point is examined. ステートメントごとにS
、最も内側のステートメントで始まり、最も外側のステートメントでtry
終了すると、try
次の手順が評価されます。For each statementS
, starting with the innermosttry
statement and ending with the outermosttry
statement, the following steps are evaluated:try
のブロックがS
スローポイントを囲み、S に1つ以上の句が含まれている場合は、catch
catch
「 try ステートメント」セクションで指定されている規則に従って、例外に適したハンドラーを検索するために、外観の順序で句が調べられます。If thetry
block ofS
encloses the throw point and if S has one or morecatch
clauses, thecatch
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 matchingcatch
clause is located, the exception propagation is completed by transferring control to the block of thatcatch
clause.それ以外の場合、
try
ブロックまたはcatch
のブロックがS
スローポイントを囲む場合、およびにブロックがある場合は、S
finally
制御がブロックに転送されfinally
ます。Otherwise, if thetry
block or acatch
block ofS
encloses the throw point and ifS
has afinally
block, control is transferred to thefinally
block. ブロックでfinally
別の例外がスローされた場合、現在の例外の処理は終了します。If thefinally
block throws another exception, processing of the current exception is terminated. それ以外の場合、コントロールがブロックの終点に到達すると、finally
現在の例外の処理が続行されます。Otherwise, when control reaches the end point of thefinally
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:
現在の関数が非同期でない場合、上記の手順は関数の呼び出し元に対して、関数メンバーが呼び出されたステートメントに対応する throw ポイントを使用して繰り返されます。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.
現在の関数が非同期でタスクを返す場合、例外は return タスクに記録されます。これは、「 列挙子インターフェイス」で説明されているように、エラーまたはキャンセル状態になります。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.
現在の関数が async および 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:
try
ブロックの後に1つ以上のブロックが続きcatch
ます。Atry
block followed by one or morecatch
blocks.- ブロックの
try
後にブロックが続くfinally
。Atry
block followed by afinally
block. - ブロックの後に1つ以上のブロックが続き、
try
catch
その後にブロックが続きfinally
ます。Atry
block followed by one or morecatch
blocks followed by afinally
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.
catch
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
句は、型を指定するものとは意味が異なり 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
break
、 continue
、または goto
ステートメントがブロックの外部で制御を転送する場合、コンパイル時エラーになり finally
ます。It is a compile-time error for a break
, continue
, or goto
statement to transfer control out of a finally
block. break
、 continue
、または 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.
try
ステートメントは次のように実行されます。A try
statement is executed as follows:
コントロールはブロックに転送され
try
ます。Control is transferred to thetry
block.コントロールがブロックの終点に到達した場合は、
try
次のようになります。When and if control reaches the end point of thetry
block:- ステートメントにブロックがある場合は、
try
finally
finally
ブロックが実行されます。If thetry
statement has afinally
block, thefinally
block is executed. - 制御は、ステートメントのエンドポイントに転送され
try
ます。Control is transferred to the end point of thetry
statement.
- ステートメントにブロックがある場合は、
ブロックの実行中に例外がステートメントに反映される場合は、
try
try
次のようになります。If an exception is propagated to thetry
statement during execution of thetry
block:catch
句 (存在する場合) は、例外に適したハンドラーを見つけるために、表示順に調べられます。Thecatch
clauses, if any, are examined in order of appearance to locate a suitable handler for the exception.catch
句が型を指定しない場合、または例外の種類または例外の種類の基本型を指定する場合は、次のようになります。If acatch
clause does not specify a type, or specifies the exception type or a base type of the exception type:- 句で例外変数が宣言されている場合、例外
catch
オブジェクトは例外変数に割り当てられます。If thecatch
clause declares an exception variable, the exception object is assigned to the exception variable. - 句で
catch
例外フィルターを宣言すると、フィルターが評価されます。If thecatch
clause declares an exception filter, the filter is evaluated. と評価された場合false
、catch 句は一致しないため、catch
適切なハンドラーの後続の句の中で検索が続行されます。If it evaluates tofalse
, the catch clause is not a match, and the search continues through any subsequentcatch
clauses for a suitable handler. - それ以外の場合、
catch
句は一致と見なされ、制御は一致するブロックに転送されcatch
ます。Otherwise, thecatch
clause is considered a match, and control is transferred to the matchingcatch
block. - コントロールがブロックの終点に到達した場合は、
catch
次のようになります。When and if control reaches the end point of thecatch
block:- ステートメントにブロックがある場合は、
try
finally
finally
ブロックが実行されます。If thetry
statement has afinally
block, thefinally
block is executed. - 制御は、ステートメントのエンドポイントに転送され
try
ます。Control is transferred to the end point of thetry
statement.
- ステートメントにブロックがある場合は、
- ブロックの実行中に例外がステートメントに反映される場合は、
try
catch
次のようになります。If an exception is propagated to thetry
statement during execution of thecatch
block:- ステートメントにブロックがある場合は、
try
finally
finally
ブロックが実行されます。If thetry
statement has afinally
block, thefinally
block is executed. - 例外は、次の外側のステートメントに反映され
try
ます。The exception is propagated to the next enclosingtry
statement.
- ステートメントにブロックがある場合は、
- 句で例外変数が宣言されている場合、例外
- ステートメントに句が含まれていない場合、
try
catch
またはcatch
句が例外に一致しない場合は、次のようになります。If thetry
statement has nocatch
clauses or if nocatch
clause matches the exception:- ステートメントにブロックがある場合は、
try
finally
finally
ブロックが実行されます。If thetry
statement has afinally
block, thefinally
block is executed. - 例外は、次の外側のステートメントに反映され
try
ます。The exception is propagated to the next enclosingtry
statement.
- ステートメントにブロックがある場合は、
finally
コントロールがステートメントを離れると、常にブロックのステートメントが実行され try
ます。The statements of a finally
block are always executed when control leaves a try
statement. これは break
、、、、またはステートメントを実行した結果として、通常の実行の結果として制御転送が行われるか、 continue
goto
またはステートメントから 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.
ステートメントに到達できる catch
場合、ステートメントのブロックに 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 thetry
block is reachable or the end point of at least onecatch
block is reachable. finally
ブロックが存在する場合は、ブロックのエンドポイントにfinally
到達できます。If afinally
block is present, the end point of thefinally
block is reachable.
checked および unchecked ステートメントThe checked and unchecked statements
checked
およびステートメントは、 unchecked
整数型の算術演算および変換の オーバーフローチェックコンテキスト を制御するために使用されます。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.
ステートメントとステートメントは、式では checked
unchecked
checked
unchecked
なくブロックで動作する点を除いて、and 演算子 (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.
lock
フォームのステートメント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
;
リソース とは、を実装するクラスまたは構造体です 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_acquisition の形式が local_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 の形式が expression の場合、この式はに暗黙的に変換可能である必要があり 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.
using
ステートメントは、取得、使用、および破棄という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.
using
フォームのステートメントA using
statement of the form
using (ResourceType resource = expression) statement
考えられる3つの展開のいずれかに対応します。corresponds to one of three possible expansions. ResourceType
が null 非許容の値型である場合、拡張はWhen ResourceType
is a non-nullable value type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}
それ以外の場合、 ResourceType
が 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();
}
}
それ以外の場合、がの場合、 ResourceType
dynamic
拡張は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.
using
フォームのステートメント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. using
フォームのステートメント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);
}
}
}
}
TextWriter
クラスとクラスはインターフェイスを実装するため、この TextReader
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_body の外側、 operator_body または accessor_body に表示される場合、コンパイル時にエラーが発生します。It is a compile-time error for ayield
statement (of either form) to appear outside a method_body, operator_body or accessor_bodyyield
ステートメント (いずれかの形式) が匿名関数内に出現する場合、コンパイル時エラーになります。It is a compile-time error for ayield
statement (of either form) to appear inside an anonymous function.- ステートメントが
yield
ステートメントの句に記述されている場合は、コンパイル時にエラーになりfinally
try
ます。It is a compile-time error for ayield
statement (of either form) to appear in thefinally
clause of atry
statement. yield return
ステートメントが任意の句を含むステートメント内の任意の場所に出現する場合、コンパイル時エラーになりtry
catch
ます。It is a compile-time error for ayield return
statement to appear anywhere in atry
statement that contains anycatch
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 型 (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.
yield 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 theCurrent
property of the enumerator object. - 反復子ブロックの実行が中断されています。Execution of the iterator block is suspended.
yield return
ステートメントが1つ以上のブロック内にある場合try
、関連付けられたブロックは現時点では実行されfinally
ません。If theyield return
statement is within one or moretry
blocks, the associatedfinally
blocks are not executed at this time. MoveNext
列挙子オブジェクトのメソッドは、true
その呼び出し元にを返します。これは、列挙子オブジェクトが次の項目に正常に進んだことを示します。TheMoveNext
method of the enumerator object returnstrue
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.
yield break
ステートメントは次のように実行されます。A yield break
statement is executed as follows:
yield break
ステートメントが、関連付けられたブロックがある1つ以上のブロックによって囲まれている場合try
finally
、最初にコントロールがfinally
最も内側のステートメントのブロックに転送されtry
ます。If theyield break
statement is enclosed by one or moretry
blocks with associatedfinally
blocks, control is initially transferred to thefinally
block of the innermosttry
statement. コントロールがブロックの終点に到達した場合finally
、コントロールはfinally
次の外側のステートメントのブロックに転送されtry
ます。When and if control reaches the end point of afinally
block, control is transferred to thefinally
block of the next enclosingtry
statement. このプロセスは、finally
外側のすべてのステートメントのブロックが実行されるまで繰り返されtry
ます。This process is repeated until thefinally
blocks of all enclosingtry
statements have been executed.- コントロールは、反復子ブロックの呼び出し元に返されます。Control is returned to the caller of the iterator block. これは、
MoveNext
Dispose
列挙子オブジェクトのメソッドまたはメソッドのいずれかです。This is either theMoveNext
method orDispose
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.