変数Variables

変数は、ストレージの場所を表します。Variables represent storage locations. すべての変数には、変数に格納できる値を決定する型があります。Every variable has a type that determines what values can be stored in the variable. C#はタイプセーフな言語であり、コンパイラC#は変数に格納されている値が常に適切な型であることを保証します。C# is a type-safe language, and the C# compiler guarantees that values stored in variables are always of the appropriate type. 変数の値は、代入によって、または演算子++--演算子を使用して変更できます。The value of a variable can be changed through assignment or through use of the ++ and -- operators.

値を取得する前に、変数を確実に代入 (明確な代入) する必要があります。A variable must be definitely assigned (Definite assignment) before its value can be obtained.

以下のセクションで説明するように、変数は最初に割り当てられるか、最初に割り当てが解除されます。As described in the following sections, variables are either initially assigned or initially unassigned. 最初に割り当てられた変数には、明確に定義された初期値があり、常に割り当てられていると見なされます。An initially assigned variable has a well-defined initial value and is always considered definitely assigned. 初期値が割り当てられていない変数には初期値がありません。An initially unassigned variable has no initial value. 最初に割り当てられていない変数を特定の場所で確実に割り当てられるようにするには、その場所に至る可能性のあるすべての実行パスで、変数への代入を行う必要があります。For an initially unassigned variable to be considered definitely assigned at a certain location, an assignment to the variable must occur in every possible execution path leading to that location.

変数のカテゴリVariable categories

C#変数の7つのカテゴリ (静的変数、インスタンス変数、配列要素、値パラメーター、参照パラメーター、出力パラメーター、およびローカル変数) を定義します。C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. 以下のセクションでは、これらの各カテゴリについて説明します。The sections that follow describe each of these categories.

この例では、In the example

class A
{
    public static int x;
    int y;

    void F(int[] v, int a, ref int b, out int c) {
        int i = 1;
        c = a + b++;
    }
}

xは静的y変数、はインスタンスv[0]変数、は配列要素a 、はc値パラメーター b 、は参照パラメーター、は出力パラメーター i 、はローカル変数です.x is a static variable, y is an instance variable, v[0] is an array element, a is a value parameter, b is a reference parameter, c is an output parameter, and i is a local variable.

静的変数Static variables

static修飾子を使用して宣言されたフィールドは、静的変数と呼ばれます。A field declared with the static modifier is called a static variable. 静的変数は、それを含んでいる型に対して静的コンストラクター (静的コンストラクター) を実行する前に存在し、関連付けられているアプリケーションドメインが存在しなくなったときには存在しなくなります。A static variable comes into existence before execution of the static constructor (Static constructors) for its containing type, and ceases to exist when the associated application domain ceases to exist.

静的変数の初期値は、変数の型の既定値 (既定値) です。The initial value of a static variable is the default value (Default values) of the variable's type.

確実な代入のチェックのために、静的変数は最初に割り当てられたものと見なされます。For purposes of definite assignment checking, a static variable is considered initially assigned.

インスタンス変数Instance variables

修飾子をstatic指定せずに宣言されたフィールドは、インスタンス変数と呼ばれます。A field declared without the static modifier is called an instance variable.

クラスのインスタンス変数Instance variables in classes

クラスのインスタンス変数は、そのクラスの新しいインスタンスが作成されるときに存在し、そのインスタンスへの参照がなく、インスタンスのデストラクター (存在する場合) が実行されたときに存在しなくなります。An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance's destructor (if any) has executed.

クラスのインスタンス変数の初期値は、変数の型の既定値 (既定値) です。The initial value of an instance variable of a class is the default value (Default values) of the variable's type.

明確な代入を確認するために、クラスのインスタンス変数は最初に割り当てられたものと見なされます。For the purpose of definite assignment checking, an instance variable of a class is considered initially assigned.

構造体のインスタンス変数Instance variables in structs

構造体のインスタンス変数の有効期間は、それが属する構造体変数とまったく同じです。An instance variable of a struct has exactly the same lifetime as the struct variable to which it belongs. つまり、構造体型の変数が存在する場合、または存在しなくなった場合は、構造体のインスタンス変数を取得します。In other words, when a variable of a struct type comes into existence or ceases to exist, so too do the instance variables of the struct.

構造体のインスタンス変数の初期割り当ての状態は、それを含んでいる構造体の変数と同じです。The initial assignment state of an instance variable of a struct is the same as that of the containing struct variable. つまり、構造体変数が最初に割り当てられていると見なされると、そのインスタンス変数もあります。また、struct 変数が最初に割り当てられていないと見なされると、そのインスタンス変数は同様に割り当て解除されます。In other words, when a struct variable is considered initially assigned, so too are its instance variables, and when a struct variable is considered initially unassigned, its instance variables are likewise unassigned.

配列要素Array elements

配列の要素は、配列インスタンスの作成時に存在し、その配列インスタンスへの参照がない場合は存在しなくなります。The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance.

配列の各要素の初期値は、配列要素の型の既定値 (既定値) です。The initial value of each of the elements of an array is the default value (Default values) of the type of the array elements.

明確な割り当てチェックのために、配列要素は最初に割り当てられたと見なされます。For the purpose of definite assignment checking, an array element is considered initially assigned.

値パラメーターValue parameters

またはref out修飾子を指定せずに宣言されたパラメーターは、値パラメーターです。A parameter declared without a ref or out modifier is a value parameter.

値パラメーターは、関数メンバー (メソッド、インスタンスコンストラクター、アクセサー、または演算子) の呼び出し時、またはパラメーターが属する匿名関数の呼び出し時に存在し、呼び出しで指定された引数の値で初期化されます。A value parameter comes into existence upon invocation of the function member (method, instance constructor, accessor, or operator) or anonymous function to which the parameter belongs, and is initialized with the value of the argument given in the invocation. 通常、値パラメーターは、関数メンバーまたは匿名関数を返したときに存在しなくなります。A value parameter normally ceases to exist upon return of the function member or anonymous function. ただし、値パラメーターが匿名関数 (匿名関数式) によってキャプチャされる場合、その匿名関数から作成されたデリゲートまたは式ツリーがガベージコレクションの対象になるまで、その有効期間は少なくともになります。However, if the value parameter is captured by an anonymous function (Anonymous function expressions), its life time extends at least until the delegate or expression tree created from that anonymous function is eligible for garbage collection.

明確な割り当てチェックのために、値パラメーターは最初に割り当てられたと見なされます。For the purpose of definite assignment checking, a value parameter is considered initially assigned.

参照パラメーターReference parameters

修飾子をref使用して宣言されたパラメーターは参照パラメーターです。A parameter declared with a ref modifier is a reference parameter.

参照パラメーターでは、新しいストレージの場所は作成されません。A reference parameter does not create a new storage location. 代わりに、参照パラメーターは、関数メンバーまたは匿名関数呼び出しで引数として指定された変数と同じ格納場所を表します。Instead, a reference parameter represents the same storage location as the variable given as the argument in the function member or anonymous function invocation. したがって、参照パラメーターの値は、常に基になる変数と同じになります。Thus, the value of a reference parameter is always the same as the underlying variable.

参照パラメーターには、次の明確な代入規則が適用されます。The following definite assignment rules apply to reference parameters. 出力パラメーター」で説明されている出力パラメーターのさまざまな規則に注意してください。Note the different rules for output parameters described in Output parameters.

  • 変数は、関数メンバーまたはデリゲート呼び出しで参照パラメーターとして渡す前に、確実に代入 (明確な代入) する必要があります。A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter in a function member or delegate invocation.
  • 関数メンバーまたは匿名関数内では、参照パラメーターは最初に割り当てられたと見なされます。Within a function member or anonymous function, a reference parameter is considered initially assigned.

インスタンスメソッドまたは構造体型のインスタンスアクセサー内ではthis 、キーワードは構造体型の参照パラメーターとまったく同じように動作します (このアクセス)。Within an instance method or instance accessor of a struct type, the this keyword behaves exactly as a reference parameter of the struct type (This access).

出力パラメーターOutput parameters

out修飾子を使用して宣言されたパラメーターは、出力パラメーターです。A parameter declared with an out modifier is an output parameter.

出力パラメーターでは、新しいストレージの場所は作成されません。An output parameter does not create a new storage location. 代わりに、出力パラメーターは、関数メンバーまたはデリゲート呼び出しの引数として指定された変数と同じ格納場所を表します。Instead, an output parameter represents the same storage location as the variable given as the argument in the function member or delegate invocation. したがって、出力パラメーターの値は、常に基になる変数と同じになります。Thus, the value of an output parameter is always the same as the underlying variable.

出力パラメーターには、次の明確な代入規則が適用されます。The following definite assignment rules apply to output parameters. 参照パラメーターについては、「参照パラメーター」で説明しているさまざまな規則に注意してください。Note the different rules for reference parameters described in Reference parameters.

  • 変数は、関数メンバーまたはデリゲート呼び出しの出力パラメーターとして渡す前に、確実に割り当てる必要はありません。A variable need not be definitely assigned before it can be passed as an output parameter in a function member or delegate invocation.
  • 関数メンバーの通常の完了またはデリゲート呼び出しの後に、出力パラメーターとして渡された各変数は、その実行パスで割り当てられていると見なされます。Following the normal completion of a function member or delegate invocation, each variable that was passed as an output parameter is considered assigned in that execution path.
  • 関数メンバーまたは匿名関数内では、出力パラメーターは最初に割り当てられていないと見なされます。Within a function member or anonymous function, an output parameter is considered initially unassigned.
  • 関数メンバーまたは匿名関数のすべての出力パラメーターは、関数メンバーまたは匿名関数が正常に返される前に、確実に代入される必要があります (明確な代入)。Every output parameter of a function member or anonymous function must be definitely assigned (Definite assignment) before the function member or anonymous function returns normally.

構造体型のインスタンスコンストラクター内では、 thisキーワードは構造体型の出力パラメーターとして正確に動作します (このアクセス)。Within an instance constructor of a struct type, the this keyword behaves exactly as an output parameter of the struct type (This access).

ローカル変数Local variables

ローカル変数は、 local_variable_declarationによって宣言されます。これは、ブロックfor_statementswitch_statement 、またはusing_statementで発生する可能性があります。または、 foreach_statementまたはtry_statementspecific_catch_clauseA local variable is declared by a local_variable_declaration, which may occur in a block, a for_statement, a switch_statement or a using_statement; or by a foreach_statement or a specific_catch_clause for a try_statement.

ローカル変数の有効期間は、ストレージが予約されていることが保証されるプログラム実行の部分です。The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. この有効期間は、少なくともの entry から、それが関連付けられているblockfor_statementswitch_statementusing_statementforeach_statement、またはspecific_catch_clauseにまで及びます。そのblockfor_statementswitch_statementusing_statementforeach_statement、またはspecific_catch_clauseの実行は、どのような形で終了します。This lifetime extends at least from entry into the block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause with which it is associated, until execution of that block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause ends in any way. (囲まれたブロックを入力するか、メソッドを呼び出すと、現在のブロックfor_statementswitch_statementusing_statementforeach_statement、または specific_ の実行が中断されますが、終了することはありません。 catch_clause)ローカル変数が匿名関数 (キャプチャされた外部変数) によってキャプチャされる場合、その有効期間は、匿名関数から作成されたデリゲートまたは式ツリーと、キャプチャされた変数は、ガベージコレクションの対象になります。(Entering an enclosed block or calling a method suspends, but does not end, execution of the current block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause.) If the local variable is captured by an anonymous function (Captured outer variables), its lifetime extends at least until the delegate or expression tree created from the anonymous function, along with any other objects that come to reference the captured variable, are eligible for garbage collection.

ブロックfor_statementswitch_statementusing_statementforeach_statement、またはspecific_catch_clauseが再帰的に入力されると、ローカル変数の新しいインスタンスが作成されます。時間とそのlocal_variable_initializerがある場合は、毎回評価されます。If the parent block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause is entered recursively, a new instance of the local variable is created each time, and its local_variable_initializer, if any, is evaluated each time.

Local_variable_declarationによって導入されるローカル変数は自動的に初期化されないため、既定値はありません。A local variable introduced by a local_variable_declaration is not automatically initialized and thus has no default value. 明確な割り当てチェックの目的で、 local_variable_declarationによって導入されたローカル変数は、最初に未割り当てと見なされます。For the purpose of definite assignment checking, a local variable introduced by a local_variable_declaration is considered initially unassigned. Local_variable_declarationには、 local_variable_initializerを含めることができます。この場合、変数は初期化式 (宣言ステートメント) の後にのみ確実に割り当てられたと見なされます。A local_variable_declaration may include a local_variable_initializer, in which case the variable is considered definitely assigned only after the initializing expression (Declaration statements).

Local_variable_declarationによって導入されるローカル変数のスコープ内では、そのローカル変数をlocal_variable_declaratorの前にあるテキスト位置で参照するコンパイル時エラーになります。Within the scope of a local variable introduced by a local_variable_declaration, it is a compile-time error to refer to that local variable in a textual position that precedes its local_variable_declarator. ローカル変数宣言が暗黙的 (ローカル変数宣言) である場合は、 local_variable_declarator内で変数を参照することもエラーになります。If the local variable declaration is implicit (Local variable declarations), it is also an error to refer to the variable within its local_variable_declarator.

Foreach_statementまたはspecific_catch_clauseによって導入されたローカル変数は、そのスコープ全体で確実に割り当てられていると見なされます。A local variable introduced by a foreach_statement or a specific_catch_clause is considered definitely assigned in its entire scope.

ローカル変数の実際の有効期間は実装に依存します。The actual lifetime of a local variable is implementation-dependent. たとえば、コンパイラは、ブロック内のローカル変数が、そのブロックの一部にのみ使用されることを静的に判断する場合があります。For example, a compiler might statically determine that a local variable in a block is only used for a small portion of that block. この分析を使用すると、コンパイラは、変数のストレージの有効期間が、それを含んでいるブロックよりも短くなるようなコードを生成できます。Using this analysis, the compiler could generate code that results in the variable's storage having a shorter lifetime than its containing block.

ローカル参照変数によって参照されるストレージは、ローカル参照変数の有効期間 (自動メモリ管理) とは無関係に再利用されます。The storage referred to by a local reference variable is reclaimed independently of the lifetime of that local reference variable (Automatic memory management).

既定の値Default values

次のカテゴリの変数は、自動的に既定値に初期化されます。The following categories of variables are automatically initialized to their default values:

  • 静的変数Static variables.
  • クラスインスタンスのインスタンス変数。Instance variables of class instances.
  • 配列要素。Array elements.

変数の既定値は、変数の型によって異なり、次のように決定されます。The default value of a variable depends on the type of the variable and is determined as follows:

  • Value_typeの変数の既定値は、 value_typeの既定のコンストラクター (既定のコンストラクター) によって計算された値と同じです。For a variable of a value_type, the default value is the same as the value computed by the value_type's default constructor (Default constructors).
  • Reference_typeの変数の場合、既定値はnullです。For a variable of a reference_type, the default value is null.

既定値への初期化は、通常、メモリマネージャーまたはガベージコレクターが、使用のために割り当てられる前にすべてのビットゼロにメモリを初期化することによって行われます。Initialization to default values is typically done by having the memory manager or garbage collector initialize memory to all-bits-zero before it is allocated for use. このため、null 参照を表すためにすべて-bit-0 を使用すると便利です。For this reason, it is convenient to use all-bits-zero to represent the null reference.

明確な代入Definite assignment

関数メンバーの実行可能コード内の特定の場所では、コンパイラが特定の静的フロー分析 (明確な代入を決定するための正確な規則) によって、変数が確実に代入される場合、変数は確実に割り当てられると言われます。が自動的に初期化されたか、少なくとも1つの割り当ての対象になっています。At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by a particular static flow analysis (Precise rules for determining definite assignment), that the variable has been automatically initialized or has been the target of at least one assignment. 非公式に言うと、明確な割り当ての規則は次のとおりです。Informally stated, the rules of definite assignment are:

上記の非公式な規則の基になる正式な仕様については、最初に割り当てられた変数、初期未割り当ての変数、明確な割り当てを決定するための正確な規則について説明します。The formal specification underlying the above informal rules is described in Initially assigned variables, Initially unassigned variables, and Precise rules for determining definite assignment.

Struct_type変数のインスタンス変数の明示的な割り当ての状態は、まとめて、個別に追跡されます。The definite assignment states of instance variables of a struct_type variable are tracked individually as well as collectively. 上記の規則に加えて、 struct_type変数とそのインスタンス変数には次の規則が適用されます。In addition to the rules above, the following rules apply to struct_type variables and their instance variables:

  • インスタンス変数は、含まれているstruct_type変数が確実に代入されたと見なされる場合、確実に割り当てられたと見なされます。An instance variable is considered definitely assigned if its containing struct_type variable is considered definitely assigned.
  • Struct_type変数は、各インスタンス変数が確実に割り当てられたと見なされる場合、確実に割り当てられたと見なされます。A struct_type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.

明確な代入は、次のコンテキストの要件です。Definite assignment is a requirement in the following contexts:

  • 変数は、値が取得される場所ごとに確実に割り当てられる必要があります。A variable must be definitely assigned at each location where its value is obtained. これにより、未定義の値が発生することはありません。This ensures that undefined values never occur. 式での変数の出現は、の場合を除き、変数の値を取得すると見なされます。The occurrence of a variable in an expression is considered to obtain the value of the variable, except when
    • 変数は、単純な代入の左オペランドです。the variable is the left operand of a simple assignment,
    • 変数は、出力パラメーターとして渡されます。the variable is passed as an output parameter, or
    • 変数はstruct_type変数で、メンバーアクセスの左オペランドとして発生します。the variable is a struct_type variable and occurs as the left operand of a member access.
  • 変数は、参照パラメーターとして渡される場所ごとに確実に代入する必要があります。A variable must be definitely assigned at each location where it is passed as a reference parameter. これにより、呼び出される関数メンバーは最初に割り当てられた参照パラメーターを考慮することができます。This ensures that the function member being invoked can consider the reference parameter initially assigned.
  • 関数メンバーのすべての出力パラメーターは、関数メンバーがを返す各場所 (ステートメントをreturn使用するか、関数メンバー本体の末尾に到達するまで) に確実に代入する必要があります。All output parameters of a function member must be definitely assigned at each location where the function member returns (through a return statement or through execution reaching the end of the function member body). これにより、関数メンバーが出力パラメーターで未定義の値を返さないようにすることができます。これにより、コンパイラは、変数への代入と同等の出力パラメーターとして変数を受け取る関数メンバーの呼び出しを考慮することができます。This ensures that function members do not return undefined values in output parameters, thus enabling the compiler to consider a function member invocation that takes a variable as an output parameter equivalent to an assignment to the variable.
  • Struct_type this instance コンストラクターの変数は、そのインスタンスコンストラクターが返す各場所で、確実に割り当てられる必要があります。The this variable of a struct_type instance constructor must be definitely assigned at each location where that instance constructor returns.

最初に割り当てられた変数Initially assigned variables

次のカテゴリの変数が最初に割り当てられたものとして分類されます。The following categories of variables are classified as initially assigned:

  • 静的変数Static variables.
  • クラスインスタンスのインスタンス変数。Instance variables of class instances.
  • 最初に割り当てられた構造体変数のインスタンス変数。Instance variables of initially assigned struct variables.
  • 配列要素。Array elements.
  • 値パラメーター。Value parameters.
  • 参照パラメーター。Reference parameters.
  • catchforeachまたはステートメントで宣言された変数。Variables declared in a catch clause or a foreach statement.

初期未割り当ての変数Initially unassigned variables

次のカテゴリの変数は、最初に未割り当てとして分類されます。The following categories of variables are classified as initially unassigned:

  • 初期割り当てられていない構造体変数のインスタンス変数。Instance variables of initially unassigned struct variables.
  • 出力パラメーター (構造体thisインスタンスコンストラクターの変数を含む)。Output parameters, including the this variable of struct instance constructors.
  • ローカル変数 ( catchforeachまたはステートメントで宣言されているものを除く)。Local variables, except those declared in a catch clause or a foreach statement.

明確な代入を決定するための正確な規則Precise rules for determining definite assignment

使用される変数が確実に代入されることを判断するために、コンパイラは、このセクションで説明したものと同等のプロセスを使用する必要があります。In order to determine that each used variable is definitely assigned, the compiler must use a process that is equivalent to the one described in this section.

コンパイラは、最初に割り当てられていない変数を1つ以上持つ各関数メンバーの本体を処理します。The compiler processes the body of each function member that has one or more initially unassigned variables. 最初に割り当てられていない変数vについて、コンパイラは、関数メンバーの次の各点でv確実な割り当て状態を判断します。For each initially unassigned variable v, the compiler determines a definite assignment state for v at each of the following points in the function member:

  • 各ステートメントの先頭にあるAt the beginning of each statement
  • 各ステートメントのエンドポイント (エンドポイントと到達可能性)At the end point (End points and reachability) of each statement
  • 別のステートメントまたはステートメントの終了位置に制御を転送する各弧On each arc which transfers control to another statement or to the end point of a statement
  • 各式の先頭にあるAt the beginning of each expression
  • 各式の最後At the end of each expression

Vの明確な割り当ての状態は、次のいずれかになります。The definite assignment state of v can be either:

  • 確実に割り当てられます。Definitely assigned. これは、可能なすべての制御フローで、 vに値が割り当てられていることを示します。This indicates that on all possible control flows to this point, v has been assigned a value.
  • 確実には割り当てられません。Not definitely assigned. boolの式の最後にある変数の状態では、明示的に代入されていない変数の状態は、次のいずれかのサブ状態に分類される場合があります。For the state of a variable at the end of an expression of type bool, the state of a variable that isn't definitely assigned may (but doesn't necessarily) fall into one of the following sub-states:
    • True 式の後に確実に割り当てられます。Definitely assigned after true expression. この状態は、ブール式が true と評価された場合にvが確実に代入されることを示しますが、ブール式が false と評価された場合には必ずしも割り当てられるとは限りません。This state indicates that v is definitely assigned if the boolean expression evaluated as true, but is not necessarily assigned if the boolean expression evaluated as false.
    • False 式の後に確実に割り当てられます。Definitely assigned after false expression. この状態は、ブール式が false と評価された場合にvが確実に割り当てられることを示しますが、ブール式が true と評価された場合に必ずしも割り当てられるとは限りません。This state indicates that v is definitely assigned if the boolean expression evaluated as false, but is not necessarily assigned if the boolean expression evaluated as true.

次の規則は、変数vの状態が各場所でどのように決定されるかを制御します。The following rules govern how the state of a variable v is determined at each location.

ステートメントの一般的な規則General rules for statements

  • vは、関数メンバー本体の先頭では確実に割り当てられません。v is not definitely assigned at the beginning of a function member body.
  • vは、到達できないステートメントの先頭に確実に割り当てられます。v is definitely assigned at the beginning of any unreachable statement.
  • 他のステートメントの先頭にあるvの明確な割り当ての状態は、そのステートメントの先頭を対象とするすべての制御フロー転送でvの確実な割り当て状態を確認することによって決定されます。The definite assignment state of v at the beginning of any other statement is determined by checking the definite assignment state of v on all control flow transfers that target the beginning of that statement. このようなすべての制御フロー転送でvが確実に割り当てられている場合は、ステートメントの先頭にvが確実に割り当てられます。If (and only if) v is definitely assigned on all such control flow transfers, then v is definitely assigned at the beginning of the statement. 可能な制御フロー転送のセットは、ステートメントの到達可能性 (エンドポイントと到達可能性) をチェックするのと同じ方法で決定されます。The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).
  • ブロックusing lock foreach checkedの終点forでの v の明確な割り当ての状態は、、、、、、、、、、またはです。 unchecked if while do switchステートメントは、そのステートメントのエンドポイントを対象とするすべての制御フロー転送でvの確実な割り当て状態を確認することによって決定されます。The definite assignment state of v at the end point of a block, checked, unchecked, if, while, do, for, foreach, lock, using, or switch statement is determined by checking the definite assignment state of v on all control flow transfers that target the end point of that statement. このようなすべての制御フロー転送でvが確実に割り当てられている場合は、ステートメントの終了時にvが確実に割り当てられます。If v is definitely assigned on all such control flow transfers, then v is definitely assigned at the end point of the statement. それ以外vは、ステートメントのエンドポイントでは確実に割り当てられません。Otherwise; v is not definitely assigned at the end point of the statement. 可能な制御フロー転送のセットは、ステートメントの到達可能性 (エンドポイントと到達可能性) をチェックするのと同じ方法で決定されます。The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).

ブロックステートメント、checked、および unchecked ステートメントBlock statements, checked, and unchecked statements

ブロック内のステートメントリストの最初のステートメント (または、ステートメントリストが空の場合は、ブロックの終了点) への、制御転送でのvの確実な割り当て状態は、ブロックの前のvの明確な代入ステートメントと同じです。、 checked、またuncheckedはステートメント。The definite assignment state of v on the control transfer to the first statement of the statement list in the block (or to the end point of the block, if the statement list is empty) is the same as the definite assignment statement of v before the block, checked, or unchecked statement.

式ステートメントExpression statements

式ステートメントのstmtには、式exprで構成されます。For an expression statement stmt that consists of the expression expr:

  • vは、 stmtの先頭にあるexprの先頭で同じ明確な割り当て状態を持ちます。v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Exprの終わりにvが明示的に割り当てられている場合は、 stmtの終点に確実に代入されます。それ以外これは、 stmtのエンドポイントでは確実に割り当てられません。If v if definitely assigned at the end of expr, it is definitely assigned at the end point of stmt; otherwise; it is not definitely assigned at the end point of stmt.

宣言ステートメントDeclaration statements

  • Stmtが初期化子を含まない宣言ステートメントである場合、 vは stmt の先頭にあるstmtの終了時点で同じ明確な割り当て状態になります。If stmt is a declaration statement without initializers, then v has the same definite assignment state at the end point of stmt as at the beginning of stmt.
  • Stmtが初期化子を持つ宣言ステートメントである場合、 vの明確な割り当ての状態は、 stmtがステートメントリストであるかのように決定されます。これには、初期化子を持つ宣言ごとに1つの代入ステートメントがあります (宣言)。If stmt is a declaration statement with initializers, then the definite assignment state for v is determined as if stmt were a statement list, with one assignment statement for each declaration with an initializer (in the order of declaration).

If ステートメントIf statements

次の形式のステートメントのstmtのif場合:For an if statement stmt of the form:

if ( expr ) then_stmt else else_stmt
  • vは、 stmtの先頭にあるexprの先頭で同じ明確な割り当て状態を持ちます。v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Exprの最後にvが明示的に割り当てられている場合、 then_stmtに制御フロー転送が割り当てられ、else 句が存在しない場合は、 else_stmtまたはstmtの終了ポイントのいずれかに確実に代入されます。If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to then_stmt and to either else_stmt or to the end-point of stmt if there is no else clause.
  • Exprの終わりに "true 式の後に明示的に代入されました" という状態がvにある場合は、制御フロー転送でthen_stmtに確実に割り当てられ、else_ への制御フロー転送では確実に割り当てられません。else 句がない場合は、stmt の終了位置に stmt またはを指定します。If v has the state "definitely assigned after true expression" at the end of expr, then it is definitely assigned on the control flow transfer to then_stmt, and not definitely assigned on the control flow transfer to either else_stmt or to the end-point of stmt if there is no else clause.
  • Exprの終わりに、 vが "false 式の後に確実に代入されました" という状態がある場合は、 else_stmtへの制御フロー転送で確実に割り当てられ、then_stmt への制御フロー転送では確実に割り当てられません。.If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to else_stmt, and not definitely assigned on the control flow transfer to then_stmt. これは、 then_stmtのエンドポイントで確実に割り当てられている場合にのみ、 stmtのエンドポイントで確実に割り当てられます。It is definitely assigned at the end-point of stmt if and only if it is definitely assigned at the end-point of then_stmt.
  • それ以外の場合、 vは、制御フロー転送でthen_stmtまたはelse_stmtのいずれかに割り当てられているとは限りません。また、else 句がない場合は、 stmtのエンドポイントにも代入されません。Otherwise, v is considered not definitely assigned on the control flow transfer to either the then_stmt or else_stmt, or to the end-point of stmt if there is no else clause.

Switch ステートメントSwitch statements

制御式switch exprを持つステートメントのstmtで、次のように指定します。In a switch statement stmt with a controlling expression expr:

  • Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭のvの状態と同じです。The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • 到達可能なスイッチブロックステートメントリストへの制御フロー転送のvの明示的な割り当て状態は、 exprの最後にvを指定した場合と同じです。The definite assignment state of v on the control flow transfer to a reachable switch block statement list is the same as the definite assignment state of v at the end of expr.

While ステートメントWhile statements

次の形式のステートメントのstmtのwhile場合:For a while statement stmt of the form:

while ( expr ) while_body
  • vは、 stmtの先頭にあるexprの先頭で同じ明確な割り当て状態を持ちます。v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Exprの最後にvが明示的に割り当てられている場合、明示的には制御フロー転送でwhile_bodyに割り当てられ、終了ポイントはstmtに割り当てられます。If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to while_body and to the end point of stmt.
  • Exprの終わりに "true 式の後に明示的に代入されました" という状態がある場合、明示的に割り当てられますが、 while_bodyへの制御フロー転送は確実に代入されますが、 stmtのエンドポイントでは確実に割り当てられません。If v has the state "definitely assigned after true expression" at the end of expr, then it is definitely assigned on the control flow transfer to while_body, but not definitely assigned at the end-point of stmt.
  • Exprの終わりにvが "false 式の後に確実に代入されました" という状態がある場合は、明示的に制御フロー転送でstmtの終了ポイントに割り当てられますが、その間の制御フロー転送では確実に割り当てられません。 本文 (_c)If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt, but not definitely assigned on the control flow transfer to while_body.

Do ステートメントDo statements

次の形式のステートメントのstmtのdo場合:For a do statement stmt of the form:

do do_body while ( expr ) ;
  • vは、stmt の先頭からdo_bodyへの制御フロー転送において、 stmtの先頭と同じように明確な割り当て状態になります。v has the same definite assignment state on the control flow transfer from the beginning of stmt to do_body as at the beginning of stmt.
  • vは、 do_bodyの終点と同様に、 exprの先頭に同じ明確な割り当て状態を持ちます。v has the same definite assignment state at the beginning of expr as at the end point of do_body.
  • Exprの最後にvが明示的に割り当てられている場合は、制御フロー転送でstmtの終点に確実に代入されます。If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt.
  • Exprの最後に、"false 式の後に確実に代入されました" という状態がvにある場合は、明示的に制御フロー転送でstmtの終点に割り当てられます。If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt.

For ステートメントFor statements

次の形式のステートメントforに対して明確な代入をチェックします。Definite assignment checking for a for statement of the form:

for ( for_initializer ; for_condition ; for_iterator ) embedded_statement

は、ステートメントが書き込まれたかのように実行されます。is done as if the statement were written:

{
    for_initializer ;
    while ( for_condition ) {
        embedded_statement ;
        for_iterator ;
    }
}

For_condition forがステートメントから省略されている場合は、上記の展開でfor_conditionがにtrue置き換えられたかのように、明確な割り当ての評価が行われます。If the for_condition is omitted from the for statement, then evaluation of definite assignment proceeds as if for_condition were replaced with true in the above expansion.

Break、continue、および goto ステートメントBreak, continue, and goto statements

break 、またはgotoステートメントによって発生する制御フロー転送の v の明確な割り当て状態は、ステートメントの先頭にある v の明確な代入の状態と同じです。 continueThe definite assignment state of v on the control flow transfer caused by a break, continue, or goto statement is the same as the definite assignment state of v at the beginning of the statement.

Throw ステートメントThrow statements

フォームのステートメントのstmtの場合For a statement stmt of the form

throw expr ;

Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭にあるvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt.

Return ステートメントReturn statements

フォームのステートメントのstmtの場合For a statement stmt of the form

return expr ;
  • Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭にあるvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt.
  • Vが出力パラメーターの場合は、次のいずれかが確実に割り当てられている必要があります。If v is an output parameter, then it must be definitely assigned either:
    • after exprafter expr
    • またfinallyは、 try ステートメントをreturn囲むまたはtry のブロック-の末尾にあります。 catch - finally - finallyor at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

次の形式のステートメントの stmt の場合:For a statement stmt of the form:

return ;
  • Vが出力パラメーターの場合は、次のいずれかが確実に割り当てられている必要があります。If v is an output parameter, then it must be definitely assigned either:
    • stmtの前before stmt
    • またfinallyは、 try ステートメントをreturn囲むまたはtry のブロック-の末尾にあります。 catch - finally - finallyor at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

Try-catch ステートメントTry-catch statements

次の形式のステートメントのstmtの場合:For a statement stmt of the form:

try try_block
catch(...) catch_block_1
...
catch(...) catch_block_n
  • Try_blockの開始時のvの明確な割り当て状態は、 stmtの開始時のvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of try_block is the same as the definite assignment state of v at the beginning of stmt.
  • Catch_block_iの開始時のvの明確な割り当ての状態 (任意のi) は、 stmtの先頭にあるvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of catch_block_i (for any i) is the same as the definite assignment state of v at the beginning of stmt.
  • Try_blockのエンドポイントで v が確実に割り当てられている場合は、 stmtのエンドポイントでのvの明確な割り当て状態が確実に割り当てられます (1 から n までのすべての catch_block_i )。).The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) v is definitely assigned at the end-point of try_block and every catch_block_i (for every i from 1 to n).

Try-finally ステートメントTry-finally statements

次の形式のステートメントのstmtのtry場合:For a try statement stmt of the form:

try try_block finally finally_block
  • Try_blockの開始時のvの明確な割り当て状態は、 stmtの開始時のvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of try_block is the same as the definite assignment state of v at the beginning of stmt.
  • Finally_blockの開始時のvの明確な割り当て状態は、 stmtの開始時のvの明確な割り当て状態と同じです。The definite assignment state of v at the beginning of finally_block is the same as the definite assignment state of v at the beginning of stmt.
  • 次のいずれかが true の場合にのみ (およびの場合のみ)、 stmtのエンドポイントでのvの明確な割り当て状態が確実に割り当てられます。The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) at least one of the following is true:
    • vtry_blockのエンドポイントで確実に割り当てられます。v is definitely assigned at the end-point of try_block
    • vfinally_blockのエンドポイントで確実に割り当てられます。v is definitely assigned at the end-point of finally_block

制御フロー goto転送 (ステートメントなど) がtry_block内で開始され、 try_blockの外部で終了した場合、v がである場合は、その制御フロー転送でvが明示的に割り当てられていると見なされます。finally_blockのエンドポイントで確実に割り当てられます。If a control flow transfer (for example, a goto statement) is made that begins within try_block, and ends outside of try_block, then v is also considered definitely assigned on that control flow transfer if v is definitely assigned at the end-point of finally_block. (これは、この制御フロー転送の別の理由でvが確実に割り当てられている場合にだけではありません)。(This is not an only if—if v is definitely assigned for another reason on this control flow transfer, then it is still considered definitely assigned.)

Try-catch ステートメントTry-catch-finally statements

次の形式のtry catch - ステートメントfinallyの-明確な代入分析。Definite assignment analysis for a try-catch-finally statement of the form:

try try_block
catch(...) catch_block_1
...
catch(...) catch_block_n
finally *finally_block*

ステートメントがステートメントを囲むtry finally try - ステートメント-であるかのように実行されます。 catchis done as if the statement were a try-finally statement enclosing a try-catch statement:

try {
    try try_block
    catch(...) catch_block_1
    ...
    catch(...) catch_block_n
}
finally finally_block

次の例では、 tryステートメントのさまざまなブロック (try ステートメント) が確実な代入にどのように影響するかを示します。The following example demonstrates how the different blocks of a try statement (The try statement) affect definite assignment.

class A
{
    static void F() {
        int i, j;
        try {
            goto LABEL;
            // neither i nor j definitely assigned
            i = 1;
            // i definitely assigned
        }

        catch {
            // neither i nor j definitely assigned
            i = 3;
            // i definitely assigned
        }

        finally {
            // neither i nor j definitely assigned
            j = 5;
            // j definitely assigned
            }
        // i and j definitely assigned
        LABEL:;
        // j definitely assigned

    }
}

Foreach ステートメントForeach statements

次の形式のステートメントのstmtのforeach場合:For a foreach statement stmt of the form:

foreach ( type identifier in expr ) embedded_statement
  • Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭のvの状態と同じです。The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • Embedded_statementまたはstmtの終点に対する制御フロー転送のvの明確な割り当て状態は、 exprの最後のvの状態と同じです。The definite assignment state of v on the control flow transfer to embedded_statement or to the end point of stmt is the same as the state of v at the end of expr.

ステートメントの使用Using statements

次の形式のステートメントのstmtのusing場合:For a using statement stmt of the form:

using ( resource_acquisition ) embedded_statement
  • Resource_acquisitionの開始時のvの明確な割り当て状態は、 stmtの先頭のvの状態と同じです。The definite assignment state of v at the beginning of resource_acquisition is the same as the state of v at the beginning of stmt.
  • Embedded_statementへの制御フロー転送でのvの明確な割り当て状態は、 resource_acquisitionの最後のvの状態と同じです。The definite assignment state of v on the control flow transfer to embedded_statement is the same as the state of v at the end of resource_acquisition.

Lock ステートメントLock statements

次の形式のステートメントのstmtのlock場合:For a lock statement stmt of the form:

lock ( expr ) embedded_statement
  • Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭のvの状態と同じです。The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • Embedded_statementへの制御フロー転送でのvの明確な割り当て状態は、 exprの最後のvの状態と同じです。The definite assignment state of v on the control flow transfer to embedded_statement is the same as the state of v at the end of expr.

Yield ステートメントYield statements

次の形式のステートメントのstmtのyield return場合:For a yield return statement stmt of the form:

yield return expr ;
  • Exprの先頭でのvの明確な割り当ての状態は、 stmtの先頭のvの状態と同じです。The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • Stmtの終了時のvの明確な割り当て状態は、 exprの最後のvの状態と同じです。The definite assignment state of v at the end of stmt is the same as the state of v at the end of expr.
  • ステートメントyield breakは、確実な割り当て状態には影響しません。A yield break statement has no effect on the definite assignment state.

単純式の一般的な規則General rules for simple expressions

リテラル (リテラル)、単純な名前 (簡易名)、メンバーアクセス式 (メンバーアクセス)、インデックス付けされていないベースアクセス式 (ベースアクセス) typeofには、次の規則が適用されます。式 (typeof 演算子)、既定値の式 (既定値の式) nameof 、および式 (値の式)The following rule applies to these kinds of expressions: literals (Literals), simple names (Simple names), member access expressions (Member access), non-indexed base access expressions (Base access), typeof expressions (The typeof operator), default value expressions (Default value expressions) and nameof expressions (Nameof expressions).

  • このような式の最後にあるvの明確な割り当ての状態は、式の先頭にあるvの明確な代入の状態と同じです。The definite assignment state of v at the end of such an expression is the same as the definite assignment state of v at the beginning of the expression.

埋め込み式を使用した式の一般的な規則General rules for expressions with embedded expressions

次の規則は、かっこで囲まれた式 (かっこで囲まれた式)、要素アクセス式 (要素アクセス)、インデックスを使用した基本アクセス式 (ベースアクセス)、増分、およびの各式に適用されます。デクリメント式 (後置インクリメントおよびデクリメント演算子前置インクリメント演算子とデクリメント演算子)、キャスト式~(キャスト式) +-単項*演算子、式、バイナリ+ -*/ 、、%、、、、、、、 << >> < <= > >=``==!=、 、as、 、、^式(算術演算子シフト演算子、関係、および型のテスト) | & is 演算子論理演算子)、複合代入式 (複合代入)、 checkedおよびunchecked式 (checked および unchecked 演算子) に加えて、配列とデリゲート作成式 (新しい演算子)。The following rules apply to these kinds of expressions: parenthesized expressions (Parenthesized expressions), element access expressions (Element access), base access expressions with indexing (Base access), increment and decrement expressions (Postfix increment and decrement operators, Prefix increment and decrement operators), cast expressions (Cast expressions), unary +, -, ~, * expressions, binary +, -, *, /, %, <<, >>, <, <=, >, >=, ==, !=, is, as, &, |, ^ expressions (Arithmetic operators, Shift operators, Relational and type-testing operators, Logical operators), compound assignment expressions (Compound assignment), checked and unchecked expressions (The checked and unchecked operators), plus array and delegate creation expressions (The new operator).

これらの各式には、無条件で決まった順序で評価される1つ以上のサブ式があります。Each of these expressions has one or more sub-expressions that are unconditionally evaluated in a fixed order. たとえば、二項%演算子は演算子の左辺、次に右辺を評価します。For example, the binary % operator evaluates the left hand side of the operator, then the right hand side. インデックス作成操作によって、インデックス付きの式が評価され、左から右に順番に各インデックス式が評価されます。An indexing operation evaluates the indexed expression, and then evaluates each of the index expressions, in order from left to right. 式のexprでは、サブ式e1, e2,..., eNがこの順序で評価されます。For an expression expr, which has sub-expressions e1, e2, ..., eN, evaluated in that order:

  • E1の開始時のvの明確な割り当ての状態は、 exprの先頭での確定代入の状態と同じです。The definite assignment state of v at the beginning of e1 is the same as the definite assignment state at the beginning of expr.
  • Eiの先頭におけるvの明確な割り当ての状態 (iが1を超える) は、前のサブ式の最後にある明確な代入の状態と同じです。The definite assignment state of v at the beginning of ei (i greater than one) is the same as the definite assignment state at the end of the previous sub-expression.
  • Exprの最後におけるvの明確な割り当ての状態は、 eNの終わりにある明確な代入の状態と同じです。The definite assignment state of v at the end of expr is the same as the definite assignment state at the end of eN

呼び出し式とオブジェクト作成式Invocation expressions and object creation expressions

次の形式の呼び出し式のexprFor an invocation expression expr of the form:

primary_expression ( arg1 , arg2 , ... , argN )

または、次の形式のオブジェクト作成式。or an object creation expression of the form:

new type ( arg1 , arg2 , ... , argN )
  • 呼び出し式の場合、 primary_expressionより前のvの明確な割り当て状態は、 exprより前のvの状態と同じです。For an invocation expression, the definite assignment state of v before primary_expression is the same as the state of v before expr.
  • 呼び出し式の場合、 arg1の前のvの明確な割り当て状態は、 primary_expression後のvの状態と同じになります。For an invocation expression, the definite assignment state of v before arg1 is the same as the state of v after primary_expression.
  • オブジェクト作成式の場合、 arg1より前のvの明確な割り当ての状態は、 exprより前のvの状態と同じになります。For an object creation expression, the definite assignment state of v before arg1 is the same as the state of v before expr.
  • 各引数argiに対して、 argi after の明示代入の状態は、正規ref表現の規則によって決定outされ、または修飾子は無視されます。For each argument argi, the definite assignment state of v after argi is determined by the normal expression rules, ignoring any ref or out modifiers.
  • 各引数argiが1より大きい場合、 argi前のvの明確な割り当ての状態は、前の引数の後のvの状態と同じになりますFor each argument argi for any i greater than one, the definite assignment state of v before argi is the same as the state of v after the previous arg.
  • 引数のいずれかで変数vout引数として渡された場合 (つまりout v、形式の引数)、 v after exprの状態は確実に代入されます。If the variable v is passed as an out argument (i.e., an argument of the form out v) in any of the arguments, then the state of v after expr is definitely assigned. それ以外v after exprの状態は、 argNの後のvの状態と同じです。Otherwise; the state of v after expr is the same as the state of v after argN.
  • 配列初期化子 (配列作成式)、オブジェクト初期化子 (オブジェクト初期化子)、コレクション初期化子 (コレクション初期化子)、および匿名オブジェクト初期化子 (匿名オブジェクトの作成) の場合式) の場合、明確な割り当ての状態は、これらの構成要素がに関して定義されている展開によって決定されます。For array initializers (Array creation expressions), object initializers (Object initializers), collection initializers (Collection initializers) and anonymous object initializers (Anonymous object creation expressions), the definite assignment state is determined by the expansion that these constructs are defined in terms of.

単純な代入式Simple assignment expressions

exprの形式w = expr_rhsは次のとおりです。For an expression expr of the form w = expr_rhs:

  • Expr_rhsより前のvの明確な割り当て状態は、 exprより前のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_rhs is the same as the definite assignment state of v before expr.
  • V after exprの明確な割り当て状態は、次のように決定されます。The definite assignment state of v after expr is determined by:
    • Wvと同じ変数の場合、 v after exprの明確な代入の状態は確実に代入されます。If w is the same variable as v, then the definite assignment state of v after expr is definitely assigned.
    • それ以外の場合、割り当てが構造体型のインスタンスコンストラクター内で行われる場合、 wがプロパティアクセスである場合、構築されるインスタンスに自動的に実装されたプロパティPが指定され、 vが非表示のバッキングフィールドになります。Pの場合、 v after exprの明確な割り当て状態は確実に代入されます。Otherwise, if the assignment occurs within the instance constructor of a struct type, if w is a property access designating an automatically implemented property P on the instance being constructed and v is the hidden backing field of P, then the definite assignment state of v after expr is definitely assigned.
    • それ以外の場合、 v after exprの明示代入の状態は、 expr_rhs後のvの明確な代入の状態と同じになります。Otherwise, the definite assignment state of v after expr is the same as the definite assignment state of v after expr_rhs.

& & (条件式および式式)&& (conditional AND) expressions

exprの形式expr_first && expr_secondは次のとおりです。For an expression expr of the form expr_first && expr_second:

  • Expr_firstより前のvの明確な割り当て状態は、 exprより前のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Expr_firstの状態が明示的に割り当てられている場合、または "true 式の後に確実に割り当てられた" 場合は、 expr_secondより前のvの明確な割り当て状態が確実に割り当てられます。The definite assignment state of v before expr_second is definitely assigned if the state of v after expr_first is either definitely assigned or "definitely assigned after true expression". それ以外の場合は、確実に割り当てられません。Otherwise, it is not definitely assigned.
  • V after exprの明確な割り当て状態は、次のように決定されます。The definite assignment state of v after expr is determined by:
    • Expr_first falseが値を持つ定数式である場合、 v after exprの明示的な代入の状態は、 expr_firstvの明示的な代入の状態と同じになります。If expr_first is a constant expression with the value false, then the definite assignment state of v after expr is the same as the definite assignment state of v after expr_first.
    • それ以外の場合、 expr_first後のvの状態が確実に割り当てられると、 v after exprの状態は確実に代入されます。Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • それ以外の場合、 v after expr_secondの状態が確実に割り当てられ、 expr_first後の状態が "false 式の後に確実に割り当てられました" になると、 v after exprの状態は確実になります。担当.Otherwise, if the state of v after expr_second is definitely assigned, and the state of v after expr_first is "definitely assigned after false expression", then the state of v after expr is definitely assigned.
    • それ以外の場合、 v after expr_secondが明示的に割り当てられているか、"true 式の後に確実に割り当てられました" の場合、 v after exprの状態は "true expression の後に確実に割り当てられます" になります。Otherwise, if the state of v after expr_second is definitely assigned or "definitely assigned after true expression", then the state of v after expr is "definitely assigned after true expression".
    • それ以外の場合は、 expr_first後のvの状態が "false expression の後に確実に割り当てられました" で、 expr_secondが "false expression の後に明示的に割り当てられました" という状態になります。exprは、"false 式の後に確実に代入されます" です。Otherwise, if the state of v after expr_first is "definitely assigned after false expression", and the state of v after expr_second is "definitely assigned after false expression", then the state of v after expr is "definitely assigned after false expression".
    • それ以外の場合、 v after exprの状態は確実に代入されません。Otherwise, the state of v after expr is not definitely assigned.

この例では、In the example

class A
{
    static void F(int x, int y) {
        int i;
        if (x >= 0 && (i = y) >= 0) {
            // i definitely assigned
        }
        else {
            // i not definitely assigned
        }
        // i not definitely assigned
    }
}

変数iは、 ifステートメントの埋め込みステートメントの1つでは確実に代入されますが、他方には存在しないと見なされます。the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. ifメソッドi (i = y)のステートメントでは、最初の埋め込みステートメントで変数が確実に代入されます。これは、式の実行が常にこの埋め込みステートメントの実行に先行するからです。 FIn the if statement in method F, the variable i is definitely assigned in the first embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. これに対して、 i変数は、2番目の埋め込みステートメントでx >= 0は確実に割り当てられません。 iこれは、false がテストされ、変数が割り当て解除されるためです。In contrast, the variable i is not definitely assigned in the second embedded statement, since x >= 0 might have tested false, resulting in the variable i being unassigned.

||(条件式または) 式|| (conditional OR) expressions

exprの形式expr_first || expr_secondは次のとおりです。For an expression expr of the form expr_first || expr_second:

  • Expr_firstより前のvの明確な割り当て状態は、 exprより前のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Expr_firstの状態が明示的に割り当てられている場合、または "false 式の後に確実に割り当てられた" 場合は、 expr_secondより前のvの明確な割り当て状態が確実に割り当てられます。The definite assignment state of v before expr_second is definitely assigned if the state of v after expr_first is either definitely assigned or "definitely assigned after false expression". それ以外の場合は、確実に割り当てられません。Otherwise, it is not definitely assigned.
  • Vの明示代入ステートメントは、次の方法で決定されます。The definite assignment statement of v after expr is determined by:
    • Expr_first trueが値を持つ定数式である場合、 v after exprの明示的な代入の状態は、 expr_firstvの明示的な代入の状態と同じになります。If expr_first is a constant expression with the value true, then the definite assignment state of v after expr is the same as the definite assignment state of v after expr_first.
    • それ以外の場合、 expr_first後のvの状態が確実に割り当てられると、 v after exprの状態は確実に代入されます。Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • それ以外の場合、 v after expr_secondの状態が確実に割り当てられ、 expr_first後のvの状態が "true expression の後に確実に割り当てられました" である場合、 v after exprの状態は確実になります。担当.Otherwise, if the state of v after expr_second is definitely assigned, and the state of v after expr_first is "definitely assigned after true expression", then the state of v after expr is definitely assigned.
    • それ以外の場合、 v after expr_secondの状態が確実に割り当てられているか、"false 式の後に確実に代入されました" の場合、 v after exprの状態は "false 式の後に確実に割り当てられます" になります。Otherwise, if the state of v after expr_second is definitely assigned or "definitely assigned after false expression", then the state of v after expr is "definitely assigned after false expression".
    • それ以外の場合は、 expr_first後のvの状態が "true expression の後に確実に割り当てられました" で、 expr_secondが "true expression の後明示的に割り当てられています" という状態になります。は "true 式の後に確実に代入されました" です。Otherwise, if the state of v after expr_first is "definitely assigned after true expression", and the state of v after expr_second is "definitely assigned after true expression", then the state of v after expr is "definitely assigned after true expression".
    • それ以外の場合、 v after exprの状態は確実に代入されません。Otherwise, the state of v after expr is not definitely assigned.

この例では、In the example

class A
{
    static void G(int x, int y) {
        int i;
        if (x >= 0 || (i = y) >= 0) {
            // i not definitely assigned
        }
        else {
            // i definitely assigned
        }
        // i not definitely assigned
    }
}

変数iは、 ifステートメントの埋め込みステートメントの1つでは確実に代入されますが、他方には存在しないと見なされます。the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. ifメソッドi (i = y)のステートメントでは、2番目の embedded ステートメントで変数が確実に代入されます。これは、式の実行が常にこの埋め込みステートメントの実行に先行するためです。 GIn the if statement in method G, the variable i is definitely assigned in the second embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. これに対して、 i変数は、最初の埋め込みステートメントでは確実x >= 0に割り当てられません。これはi 、true がテストされている可能性があり、その結果、変数が割り当て解除されるためです。In contrast, the variable i is not definitely assigned in the first embedded statement, since x >= 0 might have tested true, resulting in the variable i being unassigned.

!! (論理否定) 式(logical negation) expressions

exprの形式! expr_operandは次のとおりです。For an expression expr of the form ! expr_operand:

  • Expr_operandより前のvの明確な割り当て状態は、 exprより前のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_operand is the same as the definite assignment state of v before expr.
  • V after exprの明確な割り当て状態は、次のように決定されます。The definite assignment state of v after expr is determined by:
    • * Expr_operand * の後のvの状態が確実に割り当てられている場合、 v after exprの状態は確実に代入されます。If the state of v after *expr_operand *is definitely assigned, then the state of v after expr is definitely assigned.
    • * Expr_operand * の後のvの状態が確実に割り当てられていない場合、 v after exprの状態は確実に代入されません。If the state of v after *expr_operand *is not definitely assigned, then the state of v after expr is not definitely assigned.
    • * Expr_operand * 後のvの状態が "false 式の後に確実に割り当てられました" の場合、 v after exprの状態は "true expression の後に確実に割り当てられます" になります。If the state of v after *expr_operand *is "definitely assigned after false expression", then the state of v after expr is "definitely assigned after true expression".
    • * Expr_operand * 後のvの状態が "true expression の後に確実に割り当てられました" の場合、 v after exprの状態は、"false 式の後に確実に割り当てられます" になります。If the state of v after *expr_operand *is "definitely assigned after true expression", then the state of v after expr is "definitely assigned after false expression".

???? (null 合体) 式(null coalescing) expressions

exprの形式expr_first ?? expr_secondは次のとおりです。For an expression expr of the form expr_first ?? expr_second:

  • Expr_firstより前のvの明確な割り当て状態は、 exprより前のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Expr_secondより前のvの明確な割り当ての状態は、 expr_firstの後のvの明確な割り当て状態と同じです。The definite assignment state of v before expr_second is the same as the definite assignment state of v after expr_first.
  • Vの明示代入ステートメントは、次の方法で決定されます。The definite assignment statement of v after expr is determined by:
    • Expr_firstが定数式 (定数式) で、値が null の場合、 v after exprの状態は、 expr_secondの後のvの状態と同じになります。If expr_first is a constant expression (Constant expressions) with value null, then the state of v after expr is the same as the state of v after expr_second.
  • それ以外の場合、 v after exprの状態は、 expr_firstの後のvの明確な割り当て状態と同じになります。Otherwise, the state of v after expr is the same as the definite assignment state of v after expr_first.

?: (条件) 式?: (conditional) expressions

exprの形式expr_cond ? expr_true : expr_falseは次のとおりです。For an expression expr of the form expr_cond ? expr_true : expr_false:

  • Expr_condより前のvの明確な割り当て状態は、 exprより前のvの状態と同じです。The definite assignment state of v before expr_cond is the same as the state of v before expr.
  • 次のいずれかに当てはまる場合にのみ、 expr_trueより前のvの明確な割り当て状態が確実に割り当てられます。The definite assignment state of v before expr_true is definitely assigned if and only if one of the following holds:
    • expr_condは、値を持つ定数式です。falseexpr_cond is a constant expression with the value false
    • expr_cond後のvの状態は、確実に割り当てられるか、"true 式の後に確実に代入されました" です。the state of v after expr_cond is definitely assigned or "definitely assigned after true expression".
  • 次のいずれかに当てはまる場合にのみ、 expr_falseより前のvの明確な割り当て状態が確実に割り当てられます。The definite assignment state of v before expr_false is definitely assigned if and only if one of the following holds:
    • expr_condは、値を持つ定数式です。trueexpr_cond is a constant expression with the value true
  • expr_cond後のvの状態は、確実に割り当てられるか、"false 式の後に確実に代入されました" です。the state of v after expr_cond is definitely assigned or "definitely assigned after false expression".
  • V after exprの明確な割り当て状態は、次のように決定されます。The definite assignment state of v after expr is determined by:
    • true Expr_condが値を持つ定数式 (定数式) である場合、 v after exprの状態は、 expr_trueの後のvの状態と同じになります。If expr_cond is a constant expression (Constant expressions) with value true then the state of v after expr is the same as the state of v after expr_true.
    • それ以外の場合、 expr_condが値falseを持つ定数式 (定数式) である場合、 v after exprの状態は、 expr_falseの後のvの状態と同じになります。Otherwise, if expr_cond is a constant expression (Constant expressions) with value false then the state of v after expr is the same as the state of v after expr_false.
    • それ以外の場合、 expr_true後のvの状態が確実に割り当てられ、 expr_false後のvの状態が確実に割り当てられると、 v after exprの状態は確実に代入されます。Otherwise, if the state of v after expr_true is definitely assigned and the state of v after expr_false is definitely assigned, then the state of v after expr is definitely assigned.
    • それ以外の場合、 v after exprの状態は確実に代入されません。Otherwise, the state of v after expr is not definitely assigned.

匿名関数Anonymous functions

本文 (ブロックまたは) の本体を持つlambda_expressionまたはanonymous_method_expression exprの場合:For a lambda_expression or anonymous_method_expression expr with a body (either block or expression) body:

  • 本体より前の外部変数vの明確な割り当ての状態は、 exprより前のvの状態と同じです。The definite assignment state of an outer variable v before body is the same as the state of v before expr. つまり、外部変数の明確な割り当て状態は、匿名関数のコンテキストから継承されます。That is, definite assignment state of outer variables is inherited from the context of the anonymous function.
  • 外部変数vの明示的な代入の状態は、 exprより前のvの状態と同じです。The definite assignment state of an outer variable v after expr is the same as the state of v before expr.

The example

delegate bool Filter(int i);

void F() {
    int max;

    // Error, max is not definitely assigned
    Filter f = (int n) => n < max;

    max = 5;
    DoWork(f);
}

では、匿名関数が宣言maxされている場所が確実に割り当てられないため、コンパイル時エラーが生成されます。generates a compile-time error since max is not definitely assigned where the anonymous function is declared. The example

delegate void D();

void F() {
    int n;
    D d = () => { n = 1; };

    d();

    // Error, n is not definitely assigned
    Console.WriteLine(n);
}

では、匿名関数のへnの代入が匿名関数の外部の確実なn割り当て状態に影響を与えないため、コンパイル時エラーが生成されます。also generates a compile-time error since the assignment to n in the anonymous function has no affect on the definite assignment state of n outside the anonymous function.

変数参照Variable references

Variable_referenceは、変数として分類されるです。A variable_reference is an expression that is classified as a variable. Variable_referenceは、現在の値を取得し、新しい値を格納するためにアクセスできるストレージの場所を表します。A variable_reference denotes a storage location that can be accessed both to fetch the current value and to store a new value.

variable_reference
    : expression
    ;

C およびC++では、 variable_reference左辺値と呼ばれます。In C and C++, a variable_reference is known as an lvalue.

変数参照の原子性Atomicity of variable references

bool次のデータ型の読み取りと書き込みはint uint short ushort byte、atomic: char、、 sbytefloat、、、、、、およびの各参照型です。Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. また、前の一覧の基になる型を持つ列挙型の読み取りと書き込みもアトミックです。In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. longulong、 、decimalなど、他の型の読み取りと書き込みは、ユーザー定義型と同様にアトミックであるとは限りません。 doubleReads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic. この目的のために設計されたライブラリ関数とは別に、インクリメントまたはデクリメントの場合など、アトミック読み取り/変更/書き込みの保証はありません。Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.