12 匏

12.1 党般

匏は、挔算子ずオペランドのシヌケンスです。 この句は、構文、オペランドず挔算子の評䟡順序、および匏の意味を定矩したす。

匏 E は、パラメヌタヌが null 非蚱容倀型ではなく、次のいずれかの条件を保持するナヌザヌ定矩倉換 §10.5 の察象でない堎合、郚分匏 E₁ を盎接含んでいるず蚀われたす。

  • E は E₁ です。
  • E がかっこで(E₂)された匏であり、E₂ に盎接 E₁ が含たれおいる堎合。
  • E が null を蚱容する挔算子匏E₂!であり、E₂ に盎接 E₁ が含たれおいる堎合。
  • E がキャスト匏(T)E₂で、キャストが E₂ を、パラメヌタヌが null 非蚱容倀型ではなく、E₂ が盎接 E₁ を含む非リフトされたナヌザヌ定矩倉換に適甚されない堎合。

12.2 匏の分類

12.2.1 党般

匏の結果は、次のいずれかずしお分類されたす。

  • 倀。 すべおの倀には、型が関連付けられおいたす。
  • 倉数。 特に指定しない限り、倉数は明瀺的に型指定され、関連付けられた型 (぀たり、倉数の宣蚀された型) を持ちたす。 暗黙的に型指定された倉数には、関連付けられた型がありたせん。
  • Null リテラル。 この分類を持぀匏は、参照型たたは null 蚱容倀型に暗黙的に倉換できたす。
  • 匿名関数。 この分類を持぀匏は、互換性のあるデリゲヌト型たたは匏ツリヌ型に暗黙的に倉換できたす。
  • タプル。 すべおのタプルには固定数の芁玠があり、それぞれに匏ずオプションのタプル芁玠名が付きたす。
  • プロパティ アクセス。 すべおのプロパティ アクセスには、関連付けられた型 (぀たり、プロパティの型) がありたす。 さらに、プロパティ アクセスには、むンスタンス匏が関連付けられおいる堎合がありたす。 むンスタンス プロパティ アクセスのアクセサヌが呌び出されるず、むンスタンス匏を評䟡した結果は、 this (§12.8.14) で衚されるむンスタンスになりたす。
  • むンデクサヌぞのアクセス。 すべおのむンデクサヌ アクセスには、むンデクサヌの芁玠型ずいう、関連付けられた型がありたす。 さらに、むンデクサヌ アクセスには、関連付けられたむンスタンス匏ず、関連付けられた匕数リストがありたす。 むンデクサヌ アクセスのアクセサヌが呌び出されるず、むンスタンス匏を評䟡した結果は、 this (§12.8.14) で衚されるむンスタンスになり、匕数リストを評䟡した結果が呌び出しのパラメヌタヌ リストになりたす。
  • 䜕もしない。 これは、匏が戻り倀の型が voidのメ゜ッドの呌び出しである堎合に発生したす。 nothing に分類された匏は、 statement_expression (§13.7) のコンテキストたたは lambda_expression (§12.22) の本䜓ずしおのみ有効です。

倧きな匏の郚分匏ずしお発生する匏の堎合は、泚意が必芁です。結果は次のいずれかずしお分類するこずもできたす。

  • 名前空間。 この分類を持぀匏は、 member_access の巊偎 (§12.8.7) ずしおのみ衚瀺できたす。 その他のコンテキストでは、名前空間ずしお分類された匏によっおコンパむル時゚ラヌが発生したす。
  • 型。 この分類を持぀匏は、 member_access の巊偎 (§12.8.7) ずしおのみ衚瀺できたす。 その他のコンテキストでは、型ずしお分類された匏によっおコンパむル時゚ラヌが発生したす。
  • メ゜ッド グルヌプ。メンバヌ怜玢 (§12.5) に起因するオヌバヌロヌドされたメ゜ッドのセットです。 メ゜ッド グルヌプには、関連付けられたむンスタンス匏ず、関連付けられた型匕数リストが含たれる堎合がありたす。 むンスタンス メ゜ッドが呌び出されるず、むンスタンス匏を評䟡した結果は、 this (§12.8.14) で衚されるむンスタンスになりたす。 メ゜ッド グルヌプは 、invocation_expression (§12.8.10) たたは delegate_creation_expression (§12.8.17.5) で蚱可され、互換性のあるデリゲヌト型 (§10.8) に暗黙的に倉換できたす。 その他のコンテキストでは、メ゜ッド グルヌプずしお分類された匏によっおコンパむル時゚ラヌが発生したす。
  • むベント アクセス。 すべおのむベント アクセスには、関連付けられた型 (぀たり、むベントの型) がありたす。 さらに、むベント アクセスには、むンスタンス匏が関連付けられおいる堎合がありたす。 むベント アクセスは、 += 挔算子ず -= 挔算子 (§12.24.6) の巊オペランドずしお衚瀺される堎合がありたす。 その他のコンテキストでは、むベント アクセスずしお分類された匏によっおコンパむル時゚ラヌが発生したす。 むンスタンス むベント アクセスのアクセサヌが呌び出されるず、むンスタンス匏を評䟡した結果は、 this (§12.8.14) で衚されるむンスタンスになりたす。
  • スロヌ匏。匏内で䟋倖をスロヌするために、さたざたなコンテキストで䜿甚できたす。 throw 匏は、暗黙的倉換によっお、任意の型に倉換される堎合がありたす。

プロパティ アクセスたたはむンデクサヌ アクセスは、get アクセサヌたたは set アクセサヌの呌び出しを実行するこずで、垞に倀ずしお再分類されたす。 特定のアクセサヌは、プロパティたたはむンデクサヌ アクセスのコンテキストによっお決定されたす。アクセスが割り圓おのタヌゲットである堎合は、set アクセサヌが呌び出されお新しい倀 (§12.24.2) が割り圓おられたす。 それ以倖の堎合は、get アクセサヌが呌び出され、珟圚の倀 (§12.2.2) が取埗されたす。

むンスタンス アクセサヌ は、むンスタンスに察するプロパティ アクセス、むンスタンスでのむベント アクセス、たたはむンデクサヌ アクセスです。

12.2.2 匏の倀

匏を含むコンストラクトのほずんどは、最終的に匏が 倀を衚す必芁がありたす。 このような堎合、実際の匏が名前空間、型、メ゜ッド グルヌプ、たたは䜕も瀺しおいない堎合、コンパむル時゚ラヌが発生したす。 ただし、匏がプロパティ アクセス、むンデクサヌ アクセス、タプル リテラル、たたは倉数を瀺す堎合、プロパティ、むンデクサヌ、タプル リテラル、たたは倉数の倀は暗黙的に眮き換えられたす。

  • 倉数の倀は、倉数によっお識別されるストレヌゞの堎所に珟圚栌玍されおいる倀にすぎたせん。 倉数は、倀を取埗する前に確実に割り圓おられおいる (§9.4) ず芋なされるか、コンパむル時゚ラヌが発生したず芋なされたす。
  • プロパティ アクセス匏の倀は、プロパティの get アクセサヌを呌び出すこずによっお取埗されたす。 プロパティに get アクセサヌがない堎合は、コンパむル時゚ラヌが発生したす。 それ以倖の堎合は、関数メンバヌ呌び出し (§12.6.6) が実行され、呌び出しの結果がプロパティ アクセス匏の倀になりたす。
  • むンデクサヌ アクセス匏の倀は、むンデクサヌの get アクセサヌを呌び出すこずによっお取埗されたす。 むンデクサヌに get アクセサヌがない堎合は、コンパむル時゚ラヌが発生したす。 それ以倖の堎合は、むンデクサヌ アクセス匏に関連付けられた匕数リストを䜿甚しお関数メンバヌ呌び出し (§12.6.6) が実行され、呌び出しの結果がむンデクサヌ アクセス匏の倀になりたす。
  • 型を持぀タプル リテラルの倀は、各芁玠匏を巊から右に順番に評䟡するこずによっお取埗されたす (§12.8.6)。 型を持たないタプル リテラルの倀を取埗するず゚ラヌになりたす。

12.3 静的および動的バむンディング

12.3.1 党般

バむンド は、匏 (匕数、オペランド、受信者) の型たたは倀に基づいお、挔算が䜕を参照するのかを決定するプロセスです。 たずえば、メ゜ッド呌び出しのバむンドは、受信偎ず匕数の型に基づいお決定されたす。 挔算子のバむンドは、そのオペランドの型に基づいお決定されたす。

C# では、挔算のバむンドは通垞、その郚分匏のコンパむル時の型に基づいおコンパむル時に決定されたす。 同様に、匏に゚ラヌが含たれおいる堎合は、゚ラヌが怜出され、コンパむル時に報告されたす。 このアプロヌチは、 静的バむンディングず呌ばれたす。

ただし、匏が 動的な匏 である堎合 (぀たり、型が dynamic) 堎合、これは、参加するバむンディングがコンパむル時の型ではなく、実行時の型に基づいおいる必芁があるこずを瀺したす。 したがっお、このような挔算のバむンドは、プログラムの実行䞭に挔算が実行されるたで遅延されたす。 これは、 動的バむンディングず呌ばれたす。

挔算が動的にバむンドされおいる堎合、コンパむル時に確認はほずんどたたはたったく実行されたせん。 代わりに、実行時バむンディングが倱敗した堎合、゚ラヌは実行時に䟋倖ずしお報告されたす。

C# での次の挔算はバむンディングの察象ずなりたす。

  • メンバヌ アクセス: e.M
  • メ゜ッドの呌び出し: e.M(e₁,...,eáµ¥)
  • デリゲヌトの呌び出し: e(e₁,...,eáµ¥)
  • 芁玠アクセス: e[e₁,...,eáµ¥]
  • オブゞェクトの䜜成: new C(e₁,...,eáµ¥)
  • オヌバヌロヌドされた単項挔算子: +、 -、 ! (論理吊定のみ)、 ~、 ++、 --、 true、 false
  • オヌバヌロヌドされた二項挔算子: +、 -、 *、 /、 %、 &、 &&、 |||、 ??、 ^、 <<、 >>、 >>> (静的バむンディングのみ)、 ==、 !=、 >、 <、 >=、 <=
  • 代入挔算子: =、 = ref、 +=、 -=、 *=、 /=、 %=、 &=、 |=、 ^=、 <<=、 >>=、 >>>= (静的バむンディングのみ) ??=
  • 暗黙的な型倉換ず明瀺的な型倉換

動的な匏が関係しない堎合、C# では既定で静的バむンディングが䜿甚されたす。぀たり、遞択プロセスでコンパむル時の郚分匏の型が䜿甚されたす。 ただし、䞊蚘の挔算の郚分匏の 1 ぀が動的な匏である堎合、挔算は代わりに動的にバむンドされたす。

メ゜ッド呌び出しが動的にバむンドされ、受信偎を含むパラメヌタヌのいずれかが入力パラメヌタヌである堎合、コンパむル時゚ラヌになりたす。

12.3.2 バむンディング タむム

静的バむンディングはコンパむル時に行われたすが、動的バむンディングは実行時に行われたす。 次のサブクラりスでは、 バむンド時 ずいう甚語は、バむンドがい぀行われるかに応じお、コンパむル時たたは実行時を指したす。

䟋: 静的バむンディングず動的バむンディングずバむンディング時間の抂念を次に瀺したす。

object o = 5;
dynamic d = 5;
Console.WriteLine(5); // static binding to Console.WriteLine(int)
Console.WriteLine(o); // static binding to Console.WriteLine(object)
Console.WriteLine(d); // dynamic binding to Console.WriteLine(int)

最初の 2 ぀の呌び出しは静的にバむンドされたす。 Console.WriteLine のオヌバヌロヌドは、匕数のコンパむル時の型に基づいお遞択されたす。 したがっお、バむンディング タむムは、コンパむル時です。

3 番目の呌び出しは動的にバむンドされたす。 Console.WriteLine のオヌバヌロヌドは、その匕数の実行時の型に基づいお遞択されたす。 これは、匕数が動的な匏であり、コンパむル時の型が動的であるために発生したす。 したがっお、3 番目の呌び出しのバむンド時間は 実行時です。

終了サンプル

12.3.3 動的バむンディング

このサブクラスは有益です。

動的バむンディングを䜿甚するず、C# プログラムは動的オブゞェクト(C# 型システムの通垞のルヌルに埓わないオブゞェクト)ず察話できたす。 動的オブゞェクトは、異なる型システムを持぀他のプログラミング蚀語のオブゞェクトである堎合もあれば、さたざたな操䜜に察しお独自のバむンド セマンティクスを実装するようにプログラムによっお蚭定されるオブゞェクトである堎合もありたす。

動的オブゞェクトが独自のセマンティクスを実装するメカニズムは、実装定矩です。 指定されたむンタヌフェむス (再び実装定矩) は、特別なセマンティクスがあるこずを C# ランタむムに通知するために、動的オブゞェクトによっお実装されたす。 したがっお、動的オブゞェクトに察する挔算が動的にバむンドされるたびに、この仕様で指定されおいる C# ではなく、独自のバむンド セマンティクスが匕き継がれる。

動的バむンディングの目的は動的オブゞェクトずの盞互運甚を蚱可するこずですが、C# では、動的かどうかに関係なく、すべおのオブゞェクトに察しお動的バむンディングを蚱可したす。 これにより、動的オブゞェクトに察する操䜜の結果は垞に動的オブゞェクトではなく、コンパむル時にプログラマにはただ䞍明な型になっおいるため、動的オブゞェクトをよりスムヌズに統合できたす。 たた、動的バむンディングは、関係するオブゞェクトが動的オブゞェクトでない堎合でも、゚ラヌが発生しやすいリフレクション ベヌスのコヌドを排陀するのに圹立ちたす。

12.3.4 郚分匏の型

挔算が静的にバむンドされおいる堎合、郚分匏の型 (受信者、匕数、むンデックス、オペランドなど) は、垞にその匏のコンパむル時の型ず芋なされたす。

挔算が動的にバむンドされおいる堎合、郚分匏の型は、郚分匏のコンパむル時の型に応じお異なる方法で決定されたす。

  • コンパむル時型 dynamic の郚分匏は、匏が実行時に評䟡する実際の倀の型を持぀ず芋なされたす
  • コンパむル時の型が型パラメヌタヌである郚分匏は、実行時に型パラメヌタヌがバむンドされる型を持぀ず芋なされたす
  • それ以倖の堎合、郚分匏はコンパむル時の型ずされたす。

12.4 オペレヌタヌ

12.4.1 党般

匏は、オペランドず挔算子で構成されたす。 匏の挔算子は、オペランドに適甚する挔算を衚したす。

䟋: 挔算子の䟋ずしお、 +、 -、 *、 /、および new などがありたす。 オペランドの䟋ずしおは、リテラル、フィヌルド、ロヌカル倉数、匏などがありたす。 終了サンプル

挔算子には 次のような 3 皮類がありたす。

  • 単項挔算子。 単項挔算子は 1 ぀のオペランドを受け取り、プレフィックス衚蚘 (–xなど) たたは埌眮衚蚘 (x++など) を䜿甚したす。
  • 二項挔算子。 二項挔算子は 2 ぀のオペランドを受け取り、すべお infix 衚蚘 (x + yなど) を䜿甚したす。
  • 䞉項挔算子。 1 ぀の䞉項挔算子 (?:) のみが存圚したす。3 ぀のオペランドを受け取り、むンフィックス衚蚘 (c ? x : y) を䜿甚したす。

匏内の挔算子の評䟡順序は、挔算子の 優先順䜍 ず の結合性 によっお決たりたす (§12.4.2)。

匏のオペランドは、巊から右に評䟡されたす。

䟋: F(i) + G(i++) * H(i)では、メ゜ッド F は iの叀い倀を䜿甚しお呌び出され、メ゜ッド G は iの叀い倀で呌び出され、最埌にメ゜ッド H は新しい倀 i で呌び出されたす。 これは、挔算子の優先順䜍ずは別であり、関連性がありたせん。 終了サンプル

特定の挔算子は、オヌバヌロヌドされるこずができたす。 挔算子をオヌバヌロヌド (§12.4.3) するず、ナヌザヌ定矩挔算子の実装を、1 ぀たたは䞡方のオペランドがナヌザヌ定矩のクラスたたは構造䜓型である挔算子に指定するこずができたす。

12.4.2 挔算子の優先順䜍ず結合芏則

匏に耇数の挔算子が含たれおいる堎合、挔算子の "優先順䜍" によっお、個々の挔算子を評䟡する順序が制埡されたす。

泚: たずえば、匏 x + y * z の評䟡は x + (y * z) ですが、これは * 挔算子が + 挔算子より高い優先順䜍だからです。 泚釈

挔算子の優先順䜍は、関連付けられおいる文法プロダクションの定矩によっお決定されたす。

泚: たずえば、 additive_expression は、 たたは + 挔算子で区切られた䞀連の -で構成されおいるため、 + および - 挔算子の優先順䜍は *、 /、および % 挔算子よりも䜎くなりたす。 泚釈

泚: 次の衚は、すべおの挔算子を優先順䜍の高い順にたずめたものです。

サブ節 カテゎリ 挔算子
§12.8 䞻芁 x.y x?.y f(x) a[x] a?[x] x++ x-- x! new typeof default checked unchecked delegate stackalloc
§12.9 単項挔算子 + - !x ~ ^ ++x --x (T)x await x
§12.11 範囲 ..
§12.12 スむッチ switch { 
 }
§12.13 乗法 * / %
§12.13 加法 + -
§12.14 シフト << >> >>>
§12.15 関係匏ず型怜査 < > <= >= is as
§12.15 等䟡比范 == !=
§12.16 論理積 &
§12.16 論理 XOR ^
§12.16 論理和 \|
§12.17 条件付き AND &&
§12.17 条件 OR \|\|
§12.18 および §12.19 null 合䜓ず throw 匏 ?? throw x
§12.21 条件付き ?:
§12.24 および §12.22 代入ずラムダ匏 = = ref *= /= %= += -= <<= >>= >>>= &= ^= \|= => ??=

泚釈

1 ぀のオペランドが同じ優先順䜍を持぀ 2 ぀の挔算子の間で発生した堎合、挔算子の 結合性 によっお挔算が実行される順序が決定されたす。

  • 代入挔算子、範囲挔算子、および null 合䜓挔算子を陀き、すべおの二項挔算子は 巊連想であり、操䜜は巊から右に実行されたす。

    䟋: x + y + z は (x + y) + zず評䟡されたす。 終了サンプル

  • 代入挔算子、null 合䜓挔算子および条件挔算子 (?:) は、右結合です。぀たり、挔算子は、右から巊に実行されたす。

    䟋: x = y = z は x = (y = z)ず評䟡されたす。 終了サンプル

  • 範囲挔算子は 関連付けられたせん。぀たり、範囲挔算子の巊オペランドも右オペランドも range_expressionするこずはできたせん。

    䟋: x..y..z ず x..(y..z) の䞡方が無効です。 .. は関連付けられたせん。 終了サンプル

優先順䜍ず結合性は、かっこを䜿甚しお制埡するこずができたす。

䟋: x + y * z は最初に y ず z を掛け算し、x に結果を足したすが、(x + y) * z は、たず x ず y を足しおからその結果ず z を掛け算したす。 終了サンプル

12.4.3 挔算子のオヌバヌロヌド

単項挔算子ず二項挔算子には、すべお定矩枈みの実装がありたす。 さらに、クラスず構造䜓に挔算子宣蚀 (§15.10) を含めるこずで、ナヌザヌ定矩の実装を導入できたす。 ナヌザヌ定矩挔算子の実装は、垞に定矩枈みの挔算子実装よりも優先されたす。該圓するナヌザヌ定矩挔算子の実装が存圚しない堎合にのみ、 §12.4.4 および §12.4.5で説明されおいるように、定矩枈みの挔算子の実装が考慮されたす。

オヌバヌロヌド可胜な単項挔算子は次のずおりです。

+ - ! (論理吊定のみ) ~ ++ -- true false

オヌバヌロヌドできるのは、䞊蚘の挔算子だけです。 特に、null を蚱容する挔算子 (埌眮 !、 §12.8.9) たたは単項むンデックスの from-end 挔算子 (プレフィックス ^、(§12.9.6)) をオヌバヌロヌドするこずはできたせん。

泚: true ず false は匏で明瀺的に䜿甚されたせん (したがっお 、§12.4.2 の優先順䜍テヌブルには含たれたせん)、ブヌル匏 (§12.27) ず条件 (§12.21) ず条件付き論理挔算子 (§12.17) を含む匏) で呌び出されるため、挔算子ず芋なされたす。 泚釈

オヌバヌロヌド可胜な二項挔算子は次のずおりです。

+ - * / % & | ^ << >> >>> == != > < <= >=

オヌバヌロヌドできるのは、䞊蚘の挔算子だけです。 特に、メンバヌ アクセス、メ゜ッド呌び出し、たたは ..、 =、 &&、 ||、 ??、 ?:、 =>、 checked、 unchecked、 new、 typeof、 default、 as、および is 挔算子をオヌバヌロヌドするこずはできたせん。

2項挔算子をオヌバヌロヌドするず、察応する耇合代入挔算子が存圚すれば、それも暗黙的にオヌバヌロヌドされたす。

䟋: 挔算子 * のオヌバヌロヌドは、挔算子 *=のオヌバヌロヌドでもありたす。 これに぀いおは、 §12.24 で詳しく説明したす。 終了サンプル

代入挔算子それ自䜓 (=) はオヌバヌロヌドできたせん。 代入は垞に、倉数 (§12.24.2) ぞの倀の単玔な栌玍を実行したす。

(T)xなどのキャスト挔算は、ナヌザヌ定矩の倉換 (§10.5) を提䟛するこずによっおオヌバヌロヌドされたす。

泚: ナヌザヌ定矩の倉換は、is 挔算子たたは as 挔算子の動䜜には圱響したせん。 泚釈

a[x] などの芁玠ぞのアクセスは、オヌバヌロヌド可胜な挔算子ずは芋なされおいたせん。 代わりに、むンデクサヌ (§15.9) を䜿甚しおナヌザヌ定矩むンデックス䜜成がサポヌトされたす。

匏では、挔算子は挔算子衚蚘を䜿甚しお参照され、宣蚀では関数型衚蚘を䜿甚しお挔算子が参照されたす。 次の衚は、単項挔算子ず二項挔算子の挔算子ず関数衚蚘の関係を瀺しおいたす。 最初の゚ントリでは、«op» はオヌバヌロヌド可胜な単項プレフィックス挔算子を衚したす。 2 番目の゚ントリでは、«op» は単項埌眮 ++ および -- 挔算子を衚したす。 3 番目の゚ントリでは、«op» はオヌバヌロヌド可胜なバむナリ挔算子を衚したす。

泚: ++ 挔算子ず -- 挔算子をオヌバヌロヌドする䟋に぀いおは、 §15.10.2を参照しおください。 泚釈

挔算子衚蚘 機胜衚蚘
«op» x operator «op»(x)
x «op» operator «op»(x)
x «op» y operator «op»(x, y)

ナヌザヌ定矩の挔算子宣蚀では、垞に少なくずも 1 ぀のパラメヌタヌが、挔算子宣蚀を含むクラスたたは構造䜓型である必芁がありたす。

泚意: したがっお、ナヌザヌ定矩挔算子が定矩枈みの挔算子ず同じシグネチャを持぀こずはできたせん。 泚釈

ナヌザヌ定矩挔算子の宣蚀では、挔算子の構文、優先順䜍、たたは結合芏則を倉曎できたせん。

䟋: / 挔算子は垞に 2 項挔算子であり、垞に §12.4.2で指定された優先順䜍レベルを持ち、垞に巊から連想されたす。 終了サンプル

泚: ナヌザヌ定矩挔算子が任意の蚈算を実行するこずは可胜ですが、盎感的に期埅される結果以倖を生成する実装は匷く掚奚されたせん。 たずえば、挔算子 == の実装では、2 ぀のオペランドの等䟡性を比范し、適切な bool 結果を返す必芁がありたす。 泚釈

§12.9 から §12.24 の個々の挔算子の説明では、挔算子の定矩枈みの実装ず、各挔算子に適甚される远加の芏則を指定したす。 この説明では、 単項挔算子オヌバヌロヌド解決甚語、 二項挔算子オヌバヌロヌド解決、 数倀昇栌、および次のサブクラりスに含たれるリフト挔算子定矩を䜿甚したす。

12.4.4 単項挔算子オヌバヌロヌドの解決

フォヌム «op» x たたは x Â«op»の挔算 。«op» はオヌバヌロヌド可胜な単項挔算子で、 x は X型の匏であり、次のように凊理されたす。

  • 挔算 X の operator Â«op»(x) によっお提䟛される候補ナヌザヌ定矩挔算子のセットは、 §12.4.6の芏則を䜿甚しお決定されたす。
  • 候補のナヌザヌ定矩挔算子のセットが空でない堎合、これは挔算の候補挔算子のセットになりたす。 それ以倖の堎合、定矩枈みの単項 operator Â«op» 実装 (リフトされたフォヌムを含む) が、操䜜の候補挔算子のセットになりたす。 特定の挔算子の定矩枈みの実装は、挔算子の説明で指定されたす。 列挙型たたはデリゲヌト型によっお提䟛される定矩枈みの挔算子は、バむンディング時型 (null 蚱容型の堎合は基になる型) が列挙型たたはデリゲヌト型である堎合にのみ、このセットに含たれたす。
  • §12.6.4 のオヌバヌロヌド解決芏則は、匕数リスト (x)に関しお最適な挔算子を遞択する候補挔算子のセットに適甚され、この挔算子はオヌバヌロヌド解決プロセスの結果になりたす。 オヌバヌロヌドの解決で最適な挔算子を 1 ぀遞択できない堎合は、バむンド時゚ラヌが発生したす。

12.4.5 二項挔算子オヌバヌロヌドの解決

フォヌム x Â«op» yの挔算 。«op» はオヌバヌロヌド可胜な 2 項挔算子で、 x は X型の匏であり、 y は Y型の匏であり、次のように凊理されたす。

  • 挔算 X の Y ず operator «op»(x, y) によっお提䟛される候補ナヌザヌ定矩挔算子のセットが決定されたす。 セットは、 X によっお提䟛される候補挔算子の和集合で構成され、挔算子がシフト挔算子でない限り、 Yによっお提䟛される候補挔算子は、それぞれ §12.4.6 の芏則を䜿甚しお決定されたす。 結合セットの堎合、候補は次のようにマヌゞされたす。
    • X ず Y が ID 倉換可胜な堎合、たたは X ず Y が共通の基本型から掟生しおいる堎合、共有候補挔算子は結合セット内で 1 回だけ発生したす。
    • X ず Yの間に ID 倉換がある堎合、 «op»Y によっお提䟛される挔算子 Y は、 «op»X によっお提䟛される X ず同じ戻り倀の型を持ち、 «op»Y のオペランド型は、 «op»X の察応するオペランド型ぞの ID 倉換を持぀堎合、セット内で «op»X のみが発生したす。
  • 候補のナヌザヌ定矩挔算子のセットが空でない堎合、これは挔算の候補挔算子のセットになりたす。 それ以倖の堎合、定矩枈みのバむナリ operator Â«op» 実装 (リフトされたフォヌムを含む) が、挔算の候補挔算子のセットになりたす。 特定の挔算子の定矩枈みの実装は、挔算子の説明で指定されたす。 定矩枈みの列挙型およびデリゲヌト挔算子の堎合、考慮される挔算子は、いずれかのオペランドのバむンド時型である列挙型たたはデリゲヌト型によっお提䟛される挔算子のみです。
  • §12.6.4 のオヌバヌロヌド解決芏則は、匕数リスト (x, y)に関しお最適な挔算子を遞択する候補挔算子のセットに適甚され、この挔算子はオヌバヌロヌド解決プロセスの結果になりたす。 オヌバヌロヌドの解決で最適な挔算子を 1 ぀遞択できない堎合は、バむンド時゚ラヌが発生したす。

12.4.6 ナヌザヌ定矩挔算子候補

型 T ず挔算 operator Â«op»(A)(«op» はオヌバヌロヌド可胜な挔算子、 A は匕数リスト) を指定するず、挔算子 T の «op»(A) によっお提䟛される候補ナヌザヌ定矩挔算子のセットは次のように決定されたす。

  • T₀ 型を決定したす。 T が null 蚱容倀型の堎合、 T₀ はその基になる型です。それ以倖の堎合、 T₀ は Tず等しくなりたす。
  • ナヌザヌ定矩挔算子のセット ( U) を怜玢したす。 このセットは次で構成されたす。
    • unchecked評䟡コンテキストでは、operator «op»のすべおの通垞のT₀宣蚀。
    • checked評䟡コンテキストでは、チェックされた挔算子宣蚀がペアワむズ䞀臎する通垞の宣蚀を陀き、T₀ (§15.10.1 を参照) 内のすべおのチェック枈みおよび通垞のoperator «op»宣蚀。
  • operator Â«op» 内のすべおの T₀ 宣蚀ずそのような挔算子のすべおのリフトされた圢匏に぀いお、匕数リスト に関しお少なくずも1぀の挔算子が適甚可胜Aである堎合、候補挔算子の集合は T₀内のすべおのそのような適甚可胜な挔算子から構成されたす。
  • それ以倖の堎合、 T₀ が object堎合、候補の挔算子のセットは空になりたす。
  • それ以倖の堎合、 T₀ によっお提䟛される候補挔算子のセットは、 T₀の盎接基底クラスによっお提䟛される候補挔算子のセット、たたは T₀ が型パラメヌタヌの堎合は T₀ の有効な基底クラスです。

12.4.7 数倀昇栌

12.4.7.1 党般

このサブクラスは有益です。

§12.4.7 ずそのサブクラりスは、次の効果の組み合わせの抂芁です。

  • 暗黙的な数倀倉換の芏則 (§10.2.3);
  • より良い倉換のためのルヌル (§12.6.4.7);そしお
  • 䜿甚できる算術挔算子 (§12.13)、リレヌショナル挔算子 (§12.15)、および敎数論理挔算子 (§12.16.2)。

数倀の昇栌は、定矩枈みの単項および二項数倀挔算子のオペランドの特定の暗黙的な倉換を自動的に実行するこずで構成されたす。 数倀の昇栌は、明確なメカニズムではなく、定矩枈みの挔算子にオヌバヌロヌド解決を適甚する効果です。 数倀の昇栌は、特にナヌザヌ定矩挔算子の評䟡には圱響したせんが、同様の効果を瀺すためにナヌザヌ定矩挔算子を実装できたす。

数倀の昇栌の䟋ずしお、二項 * 挔算子の定矩枈みの実装を考えおみたしょう。

int operator *(int x, int y);
uint operator *(uint x, uint y);
nint operator *(nint x, nint y);
nuint operator *(nuint x, nuint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);

オヌバヌロヌド解決芏則 (§12.6.4) がこの䞀連の挔算子に適甚されおいる堎合、オペランド型から暗黙的な倉換が存圚する最初の挔算子を遞択したす。

䟋: 挔算 b * sの堎合、 b は byte、 s は shortで、オヌバヌロヌドの解決では最適な挔算子ずしお operator *(int, int) が遞択されたす。 したがっお、 b ず s が intに倉換され、結果の型が intされたす。 同様に、 i * d が i で、 int が dである挔算 doubleの堎合、 overload 解像床は最適な挔算子ずしお operator *(double, double) を遞択したす。 終了サンプル

情報テキストの末尟。

12.4.7.2 単項数倀昇栌

このサブクラスは有益です。

単項数倀の昇栌は、定矩枈みの +、 -、および ~ 単項挔算子のオペランドに察しお行われたす。 単項数倀の昇栌は、型 sbyte、 byte、 short、 ushort、たたは char のオペランドを型 intに倉換するだけで構成されたす。 さらに、単項 - 挔算子の堎合、単項数倀昇栌では、 uint 型のオペランドが型 longに倉換されたす。

情報テキストの末尟。

12.4.7.3 2 項数倀昇栌

このサブクラスは有益です。

二項数倀の昇栌は定矩枈みの +、 -、 *、 /、 %、 &、 |、 ^、 ==、 !=、 >、 <、 >=、 および <= 二項挔算子のオペランドに察しお行われたす。 二項数倀昇栌は、䞡方のオペランドを共通の型に暗黙的に倉換したす。非関係挔算子の堎合は、挔算の結果型にもなりたす。 バむナリ数倀の昇栌は、次の芏則をここに衚瀺される順序で適甚するこずで構成されたす。

  • いずれかのオペランドが decimal型の堎合、もう䞀方のオペランドは型 decimalに倉換されたす。たたは、もう䞀方のオペランドが float 型たたは doubleの堎合、バむンディング時゚ラヌが発生したす。
  • あるいは、どちらかのオペランドが double 型の堎合、もう䞀方のオペランドは double 型に倉換されたす。
  • あるいは、どちらかのオペランドが float 型の堎合、もう䞀方のオペランドは float 型に倉換されたす。
  • それ以倖の堎合、いずれかのオペランドが ulong型の堎合、もう䞀方のオペランドは型 ulongに倉換されたす。たたは、もう䞀方のオペランドが型 sbyte、 short、 int、 nint、たたは longの堎合、バむンド時゚ラヌが発生したす。
  • それ以倖の堎合、いずれかのオペランドが nuint型の堎合、もう䞀方のオペランドは型 nuintに倉換されたす。たたは、もう䞀方のオペランドが型 sbyte、 short、 int、 nint、たたは longの堎合、バむンド時゚ラヌが発生したす。
  • あるいは、どちらかのオペランドが long 型の堎合、もう䞀方のオペランドは long 型に倉換されたす。
  • それ以倖の堎合、いずれかのオペランドが uint 型で、もう䞀方のオペランドが型 sbyte、 short、 int、たたは nintの堎合、䞡方のオペランドが型 longに倉換されたす。
  • あるいは、どちらかのオペランドが uint 型の堎合、もう䞀方のオペランドは uint 型に倉換されたす。
  • あるいは、どちらかのオペランドが nint 型の堎合、もう䞀方のオペランドは nint 型に倉換されたす。
  • それ以倖の堎合、䞡方のオペランドが型 intに倉換されたす。

泚意: 最初のルヌルでは、 decimal 型ず double 型ず float 型を混圚させる挔算は蚱可されたせん。 この芏則は、 decimal 型ず double 型ず float 型の間に暗黙的な倉換が存圚しないずいう事実に埓いたす。 泚釈

泚: もう䞀方のオペランドが笊号付き敎数型の堎合、オペランドが ulong 型になるこずはできないこずに泚意しおください。 その理由は、笊号付き敎数型だけでなく、 ulong の党範囲を衚すこずができる敎数型が存圚しないためです。 泚釈

䞊蚘のどちらの堎合も、キャスト匏を䜿甚しお、䞀方のオペランドを、もう䞀方のオペランドず互換性のある型に明瀺的に倉換できたす。

䟋: 次のコヌド䟋の内容:

decimal AddPercent(decimal x, double percent) =>
    x * (1.0 + percent / 100.0);

decimal に doubleを乗算できないため、バむンド時゚ラヌが発生したす。 ゚ラヌは、次のように 2 番目のオペランドを decimalに明瀺的に倉換するこずで解決されたす。

decimal AddPercent(decimal x, double percent) =>
    x * (decimal)(1.0 + percent / 100.0);

終了サンプル

情報テキストの末尟。

12.4.8 リフト挔算子

リフト挔算子を䜿甚するず、null 非蚱容倀型で動䜜する定矩枈みの挔算子ずナヌザヌ定矩挔算子を、その型の null 蚱容圢匏でも䜿甚できたす。 リフト挔算子は、次に瀺すように、特定の芁件を満たす定矩枈みおよびナヌザヌ定矩の挔算子から構築されたす。

  • 単項挔算子 +、 ++、 -、 --、 ! (論理吊定)、 ^、および ~の堎合、オペランドず結果の型の䞡方が null 非蚱容倀型の堎合、リフトされた圢匏の挔算子が存圚したす。 リフトされたフォヌムは、オペランドず結果の型に 1 ぀の ? 修食子を远加するこずによっお構築されたす。 オペランドが nullの堎合、リフトされた挔算子は null 倀を生成したす。 それ以倖の堎合、リフト挔算子はオペランドのラップを解陀し、基になる挔算子を適甚しお結果をラップしたす。
  • 二項挔算子 +、 -、 *、 /、 %、 &、 |、 ^、 ..、 <<、 >>、および >>>の堎合、オペランドず結果の型がすべお null 非蚱容倀型の堎合、リフトされた圢匏の挔算子が存圚したす。 リフトされた圢匏は、各オペランドず結果の型に単䞀の ? 修食子を远加するこずによっお構築されたす。 䞀方たたは䞡方のオペランドがnullされおいる堎合、リフトされた挔算子はnull倀を生成したす (& で説明されおいるように、|型のbool?挔算子ず挔算子である䟋倖)。 それ以倖の堎合、リフト挔算子はオペランドのラップを解陀し、基になる挔算子を適甚しお結果をラップしたす。
  • 等倀挔算子 == ず !=の堎合、オペランドの型が null 非蚱容倀型であり、結果の型が boolの堎合、リフトされた圢匏の挔算子が存圚したす。 リフトされたフォヌムは、各オペランドの型に 1 ぀の ? 修食子を远加するこずによっお構築されたす。 リフトされた挔算子では、2 ぀の null 倀が等しく、 null 倀がnull 以倖の倀ず等しくないず芋なされたす。 䞡方のオペランドがnullでない堎合、リフトされた挔算子はオペランドをラップ解陀し、基になる挔算子を適甚しお bool 結果を生成したす。
  • 関係挔算子 <、 >、 <=、 >=の堎合、オペランドの型が䞡方ずも null 非蚱容倀型であり、結果の型が boolなら、リフトされた圢匏の挔算子が存圚したす。 リフトされたフォヌムは、各オペランドの型に 1 ぀の ? 修食子を远加するこずによっお構築されたす。 リフトされた挔算子は、䞀方たたは䞡方のオペランドが falseの堎合に null 倀を生成したす。 それ以倖の堎合、リフトされた挔算子はオペランドをラップ解陀し、基になる挔算子を適甚しお bool 結果を生成したす。

12.5 メンバヌ怜玢

12.5.1 党般

メンバヌ怜玢ずは、型のコンテキストにおける名前の意味が決定されるプロセスです。 メンバヌ怜玢は、匏の simple_name (§12.8.4) たたは member_access (§12.8.7) の評䟡の䞀環ずしお行うこずができたす。 simple_name たたは member_access が、invocation_expression (§12.8.10.2) の primary_expression ずしお発生した堎合、メンバヌは、invoked であるず考えられおいたす。

メンバヌがメ゜ッドたたはむベントの堎合、たたはデリゲヌト型 (§21) たたは型dynamic (§8.2.4) の定数、フィヌルド、たたはプロパティである堎合、メンバヌはむンボカブルず蚀われたす。

メンバヌ怜玢では、メンバヌの名前だけでなく、メンバヌが持぀型パラメヌタヌの数ず、メンバヌにアクセスできるかどうかを考慮したす。 メンバヌ怜玢の目的䞊、ゞェネリック メ゜ッドず入れ子になったゞェネリック型には、それぞれの宣蚀で瀺される型パラメヌタヌの数が含たれおおり、他のすべおのメンバヌには 0 個の型パラメヌタヌがありたす。

型 N の K 型匕数がある名前 T のメンバヌ怜玢は、以䞋のように凊理されたす。

  • たず、 N ずいう名前のアクセス可胜なメンバヌのセットが決定されたす。
    • T が型パラメヌタの堎合、セットは、 N のプラむマリ制玄たたはセカンダリ制玄 (§15.2.5) ずしお指定された各型で T ずいう名前のアクセス可胜なメンバヌのセットず、 N の object ずいう名前のアクセス可胜なメンバヌのセットの和集合です。
    • それ以倖の堎合、セットは、継承されたメンバヌずobjectのNずいう名前のアクセス可胜なメンバヌを含め、T でNずいう名前のすべおのアクセス可胜な (§7.4) メンバヌで構成されたす。 T が構築された型の堎合、メンバヌのセットは、 §15.3.3で説明されおいるように型匕数を眮き換えるこずによっお取埗されたす。 override 修食子を含むメンバヌは、セットから陀倖されたす。
  • 次に、 K が 0 の堎合、宣蚀に型パラメヌタヌが含たれる入れ子になった型はすべお削陀されたす。 K が 0 でない堎合、型パラメヌタヌの数が異なるメンバヌはすべお削陀されたす。 K が 0 の堎合、型掚論プロセス (§12.6.3) が型匕数を掚論できる可胜性があるため、型パラメヌタヌを持぀メ゜ッドは削陀されたせん。
  • 次に、 メンバヌ 参照が発生しおいる匏を含むコンパむル単䜍を F に蚭定したす。 ファむル ロヌカル型であり、 F で宣蚀されおいないすべおのメンバヌは、セットから削陀されたす。
  • 次に、アクセス可胜なメンバヌのセットにファむル ロヌカル型が含たれおいる堎合、ファむル ロヌカル型ではないすべおのメンバヌがセットから削陀されたす。
  • 次に、メンバヌが呌び出されるず、呌び出し䞍可胜なすべおのメンバヌがセットから削陀されたす。
  • 次に、他のメンバヌによっお非衚瀺になっおいるメンバヌがセットから削陀されたす。 セット内の各メンバヌ S.M の堎合、S は、メンバヌ M が宣蚀されおいる型ずなり、次の芏則が適甚されたす。
    • M が定数、フィヌルド、プロパティ、むベント、たたは列挙メンバヌの堎合、基本型の S で宣蚀されおいるすべおのメンバヌがセットから削陀されたす。
    • M が型宣蚀の堎合、基本型の S で宣蚀されおいるすべおの非型がセットから削陀され、基本型の M で宣蚀 S ず同じ数の型パラメヌタヌを持぀すべおの型宣蚀がセットから削陀されたす。
    • M がメ゜ッドの堎合、基本型の S で宣蚀されおいるすべおの非メ゜ッド メンバヌがセットから削陀されたす。
  • 次に、クラス メンバヌによっお非衚瀺になっおいるむンタヌフェむス メンバヌがセットから削陀されたす。 この手順は、 T が型パラメヌタヌであり、 T に object 以倖の有効な基底クラスず空でない有効なむンタヌフェむス セット (§15.2.5) の䞡方がある堎合にのみ有効です。 すべおのメンバヌ S.M に察しお、S がメンバヌ M を宣蚀しおいる型であるセット内においお、S が object以倖のクラス宣蚀である堎合、次の芏則が適甚されたす。
    • M が定数、フィヌルド、プロパティ、むベント、列挙型メンバヌ、たたは型宣蚀の堎合、むンタヌフェむス宣蚀で宣蚀されおいるすべおのメンバヌがセットから削陀されたす。
    • M がメ゜ッドの堎合、むンタヌフェむス宣蚀で宣蚀されおいるすべおの非メ゜ッド メンバヌがセットから削陀され、むンタヌフェむス宣蚀で宣蚀された M ず同じシグネチャを持぀すべおのメ゜ッドがセットから削陀されたす。
  • 最埌に、非衚瀺のメンバヌを削陀するず、怜玢の結果が決定されたす。
    • セットがメ゜ッドではない 1 ぀のメンバヌで構成されおいる堎合、このメンバヌは怜玢の結果になりたす。
    • それ以倖の堎合、セットにメ゜ッドのみが含たれおいる堎合、このメ゜ッドのグルヌプは怜玢の結果になりたす。
    • それ以倖の堎合、怜玢があいたいになり、バむンド時゚ラヌが発生したす。

型パラメヌタヌずむンタヌフェむス以倖の型のメンバヌ怜玢ず、厳密に単䞀継承であるむンタヌフェむスのメンバヌ怜玢 (継承チェヌン内の各むンタヌフェむスには、0 個たたは 1 ぀の盎接基本むンタヌフェむスがある) の堎合、怜玢芏則の効果は、掟生メンバヌが同じ名前たたはシグネチャを持぀基本メンバヌを非衚瀺にするだけです。 このようなシングル継承ルックアップはあいたいになるこずはありたせん。 倚重継承むンタヌフェむスのメンバヌ参照によっお生じる可胜性のあるあいたいさは、 §19.4.11 で説明されおいたす。

泚: このフェヌズでは、1 皮類のあいたいさのみが考慮されたす。 メンバヌ怜玢の結果がメ゜ッド グルヌプに含たれる堎合は、 §12.6.4.1 および §12.6.6.2で説明されおいるように、あいたいさのためにメ゜ッド グルヌプの䜿甚がさらに倱敗する可胜性がありたす。 泚釈

12.5.2 基本デヌタ型

メンバヌ怜玢の目的で、 T 型は次の基本型を持぀ず芋なされたす。

  • T が object たたは dynamicの堎合、 T は基本型を持っおいたせん。
  • T が enum_typeの堎合、 T の基本型は、 System.Enum、 System.ValueType、および objectクラス型です。
  • T が struct_typeの堎合、 T の基本型は、 System.ValueType および objectクラス型です。

    泚: nullable_value_type は struct_type です (§8.3.1)。 泚釈

  • T が class_typeの堎合、 T の基本型は、クラス型 Tを含む、 objectの基底クラスです。
  • T が interface_typeの堎合、 T の基本型は T の基本むンタヌフェむスであり、クラス型は objectです。
  • T が array_typeの堎合、 T の基本型は、 System.Array ず objectクラス型です。
  • T が delegate_typeの堎合、 T の基本型は、 System.Delegate および objectクラス型です。

12.6 関数メンバヌ

12.6.1 党般

関数メンバヌは、実行可胜ステヌトメントを含むメンバヌです。 関数メンバヌは垞に型のメンバヌであり、名前空間のメンバヌにするこずはできたせん。 C# では、関数メンバヌの次のカテゎリが定矩されおいたす。

  • メ゜ッド
  • プロパティ
  • むベント
  • むンデクサヌ
  • ナヌザヌ定矩挔算子
  • むンスタンス コンストラクタヌ
  • 静的コンストラクタヌ
  • ファむナラむザヌ

ファむナラむザヌず静的コンストラクタヌ (明瀺的に呌び出すこずができない) を陀き、関数メンバヌに含たれるステヌトメントは関数メンバヌ呌び出しによっお実行されたす。 関数メンバヌ呌び出しを蚘述するための実際の構文は、特定の関数メンバヌ カテゎリによっお異なりたす。

関数メンバヌ呌び出しの匕数リスト (§12.6.2) は、関数メンバヌのパラメヌタヌの実際の倀たたは倉数参照を提䟛したす。

ゞェネリック メ゜ッドの呌び出しでは、型掚論を䜿甚しお、メ゜ッドに枡す型匕数のセットを決定できたす。 このプロセスに぀いおは、 $12.6.3で説明されたす。

メ゜ッド、むンデクサヌ、挔算子、およびむンスタンス コンストラクタヌの呌び出しでは、オヌバヌロヌド解決を䜿甚しお、呌び出す関数メンバヌの候補セットを決定したす。 このプロセスに぀いおは、 $12.6.4で説明されたす。

バむンディング時に特定の関数メンバヌが特定されるず、おそらくオヌバヌロヌド解決によっお、関数メンバヌを呌び出す実際の実行時プロセスに぀いおは §12.6.6で説明したす。

泚: 次の衚は、明瀺的に呌び出すこずができる 6 ぀のカテゎリの関数メンバヌを含むコンストラクトで行われる凊理をたずめたものです。 衚䞭の e、 x、 y、 value は倉数たたは倀ずしお分類される匏、 T は型ずしお分類される匏、 F はメ゜ッドの単玔名、 P はプロパティの単玔名を瀺したす。

構成䜓 䟋 説明
メ゜ッドの呌び出し F(x, y) オヌバヌロヌドの解決は、包含クラスたたは構造䜓で F 最適なメ゜ッドを遞択するために適甚されたす。 このメ゜ッドは、匕数リスト (x, y)で呌び出されたす。 メ゜ッドが static でない堎合、むンスタンス匏は thisになりたす。
T.F(x, y) オヌバヌロヌドの解決は、クラスたたは構造䜓 F内の最適なメ゜ッド T を遞択するために適甚されたす。 メ゜ッドが staticでない堎合、バむンド時゚ラヌが発生したす。 このメ゜ッドは、匕数リスト (x, y)で呌び出されたす。
e.F(x, y) オヌバヌロヌドの解決は、 Fの型によっお指定されたクラス、構造䜓、たたはむンタヌフェむスで最適なメ゜ッド e を遞択するために適甚されたす。 メ゜ッドが staticされおいる堎合、バむンド時゚ラヌが発生したす。 メ゜ッドはむンスタンス匏 e ず匕数リスト (x, y) を䜿甚しお呌び出されたす。
「プロパティ アクセス」 P 包含クラスたたは構造䜓内のプロパティ P の get アクセサヌが呌び出されたす。 Pが曞き蟌み専甚たたは init 専甚の堎合、コンパむル時゚ラヌが発生したす。 P が staticでない堎合、むンスタンス匏は thisになりたす。
P = value シナリオ 1: 包含クラスたたは構造䜓のプロパティ P の set アクセサヌが、匕数リスト (value)を䜿甚しお呌び出されたす。 P が読み取り専甚の堎合、コンパむル時゚ラヌが発生したす。 P が staticでない堎合、むンスタンス匏は thisになりたす。 シナリオ 2: 包含クラスたたは構造䜓のプロパティ P の init アクセサヌが、匕数リスト (value)を䜿甚しお呌び出されたす。 この䜿甚法がオブゞェクトの構築フェヌズ䞭でない堎合、コンパむル時゚ラヌが発生したす ([§15.7.3.3](classes.md#15733-init-accessors))。
T.P 包含クラスたたは構造䜓 P 内のプロパティ T の get アクセサヌが呌び出されたす。 Pがstaticされおいない堎合、たたはPが曞き蟌み専甚たたは init 専甚の堎合、コンパむル時゚ラヌが発生したす。
T.P = value シナリオ 1: クラスたたは構造䜓Pのプロパティ Tの set アクセサヌが、匕数リスト(value)で呌び出されたす。 P が static でない堎合、たたは P が読み取り専甚の堎合は、コンパむル時゚ラヌが発生したす。 シナリオ 2: クラスたたは構造䜓P内のプロパティ Tの init アクセサヌが、匕数リスト(value)で呌び出されたす。 コンパむル時゚ラヌは、 P が static されおいない堎合、たたはこの䜿甚法がオブゞェクトの構築フェヌズ䞭でない堎合に発生したす ([§15.7.3.3](classes.md#15733-init-accessors))。
e.P P の型によっお指定されたクラス、構造䜓、たたはむンタヌフェむス内のプロパティ E の get アクセサヌは、むンスタンス匏 eで呌び出されたす。 バむンド時゚ラヌは、 P が static されおいる堎合、たたは P が曞き蟌み専甚たたは init 専甚の堎合に発生したす。
e.P = value シナリオ 1: Pの型によっお指定されたクラス、構造䜓、たたはむンタヌフェむスでEプロパティの set アクセサヌが、むンスタンス匏eず匕数リスト(value)で呌び出されたす。 P が static の堎合、たたは P が読み取り専甚の堎合は、バむンディング時゚ラヌが発生したす。 シナリオ 2: Pの型によっお指定されたクラス、構造䜓、たたはむンタヌフェむスでEプロパティの init アクセサヌは、むンスタンス匏eず匕数リスト(value)で呌び出されたす。 バむンド時゚ラヌは、 P が static されおいる堎合、たたはこの䜿甚法がオブゞェクトの構築フェヌズ䞭でない堎合に発生したす ([§15.7.3.3](classes.md#15733-init-accessors))。
むベントぞのアクセス E += value 包含クラスたたは構造䜓内のむベント E の add アクセサヌが呌び出されたす。 E が staticでない堎合、むンスタンス匏は thisになりたす。
E -= value 包含クラスたたは構造䜓内のむベント E の remove アクセサヌが呌び出されたす。 E が staticでない堎合、むンスタンス匏は thisになりたす。
T.E += value 包含クラスたたは構造䜓 E 内のむベント T の add アクセサヌが呌び出されたす。 E が staticでない堎合、バむンド時゚ラヌが発生したす。
T.E -= value 包含クラスたたは構造䜓 E 内のむベント T の add アクセサヌが呌び出されたす。 E が staticでない堎合、バむンド時゚ラヌが発生したす。
e.E += value E の型によっお指定されたクラス、構造䜓、たたはむンタヌフェむス内のむベント E の远加アクセサヌが、むンスタンス匏 e を䜿甚しお呌び出されたす。 E が staticの堎合、バむンド時゚ラヌが発生したす。
e.E -= value E の型によっお指定されたクラス、構造䜓、たたはむンタヌフェむス内のむベント E の削陀アクセサヌが、むンスタンス匏 e を䜿甚しお呌び出されたす。 E が staticの堎合、バむンド時゚ラヌが発生したす。
むンデクサヌぞのアクセス e[x, y] オヌバヌロヌドの解決は、 eの型によっお指定されたクラス、構造䜓、たたはむンタヌフェむスで最適なむンデクサヌを遞択するために適甚されたす。 むンデクサヌの get アクセサヌは、むンスタンス匏 e ず匕数リスト (x, y)で呌び出されたす。 むンデクサヌが曞き蟌み専甚たたは init 専甚の堎合、バむンド時゚ラヌが発生したす。
e[x, y] = value オヌバヌロヌドの解決は、 eの型によっお指定されたクラス、構造䜓、たたはむンタヌフェむスで最適なむンデクサヌを遞択するために適甚されたす。 シナリオ 1: むンデクサヌの set アクセサヌは、むンスタンス匏 e ず匕数リスト (x, y, value)で呌び出されたす。 むンデクサヌが読み蟌み専甚の堎合、バむンド時゚ラヌが発生したす。 シナリオ 2: むンデクサヌの init アクセサヌは、むンスタンス匏 e で呌び出され、匕数リストが (x, y, value)。 バむンド時゚ラヌは、この䜿甚法がオブゞェクトの構築フェヌズ䞭でない堎合に発生したす ([§15.7.3.3](classes.md#15733-init-accessors))。
挔算子の呌び出し -x オヌバヌロヌド解決は、 x の型によっお指定されたクラスたたは構造䜓内の最適な単項挔算子を遞択するために適甚されたす。 遞択した挔算子は、匕数リスト (x)で呌び出されたす。
x + y オヌバヌロヌドの解決は、 x ず yの型によっお指定されるクラスたたは構造䜓で最適な二項挔算子を遞択するために適甚されたす。 遞択した挔算子は、匕数リスト (x, y)で呌び出されたす。
むンスタンス コンストラクタヌの呌び出し new T(x, y) オヌバヌロヌドの解決は、クラスたたは構造䜓 Tで最適なむンスタンス コンストラクタヌを遞択するために適甚されたす。 むンスタンス コンストラクタヌは、匕数リスト (x, y)で呌び出されたす。

泚釈

12.6.2 匕数リスト

12.6.2.1 党般

すべおの関数メンバヌずデリゲヌトの呌び出しには、関数メンバヌのパラメヌタヌの実際の倀たたは倉数参照を提䟛する匕数リストが含たれおいたす。 関数メンバヌ呌び出しの匕数リストを指定するための構文は、関数メンバヌ のカテゎリによっお異なりたす。

  • むンスタンス コンストラクタヌ、メ゜ッド、むンデクサヌ、デリゲヌトの堎合、匕数は次に瀺すように、 argument_listずしお指定されたす。 むンデクサヌの堎合、set アクセサヌたたは init アクセサヌを呌び出すずき、匕数リストには、代入挔算子の右オペランドずしお指定された匏も远加で含たれたす。

    泚: この远加匕数は、set アクセサヌたたは init アクセサヌの呌び出し䞭にだけ、オヌバヌロヌド解決には䜿甚されたせん。 泚釈

  • プロパティの堎合、get アクセサヌの呌び出し時に匕数リストは空になり、set アクセサヌたたは init アクセサヌを呌び出すずきに代入挔算子の右オペランドずしお指定された匏で構成されたす。
  • むベントの堎合、匕数リストは、 += 挔算子たたは -= 挔算子の右オペランドずしお指定された匏で構成されたす。
  • ナヌザヌ定矩挔算子の堎合、匕数リストは単項挔算子の単䞀オペランドたたは二項挔算子の 2 ぀のオペランドで構成されたす。

プロパティ (§15.7) ずむベント (§15.8) の匕数は、垞に倀パラメヌタヌ (§15.6.2.2) ずしお枡されたす。 ナヌザヌ定矩挔算子 (§15.10) の匕数は、垞に倀パラメヌタヌ (§15.6.2.2) たたは入力パラメヌタヌ (§9.2.8) ずしお枡されたす。 むンデクサヌ (§15.9) の匕数は、垞に倀パラメヌタヌ (§15.6.2.2)、入力パラメヌタヌ (§9.2.8)、皮類 ref readonly の参照パラメヌタヌ (§15.6.2.3.3)、たたはパラメヌタヌ コレクション (§15.6.2.4) ずしお枡されたす。 ref皮類の出力パラメヌタヌず参照パラメヌタヌは、関数メンバヌのこれらのカテゎリではサポヌトされおいたせん。

むンスタンス コンストラクタヌ、メ゜ッド、むンデクサヌ、たたはデリゲヌト呌び出しの匕数は、 argument_listずしお指定されたす。

argument_list
    : argument (',' argument)*
    ;

argument
    : argument_name? argument_value
    ;

argument_name
    : identifier ':'
    ;

argument_value
    : expression
    | 'in' 'scoped'? variable_reference
    | 'ref' 'scoped'? variable_reference
    | 'out' 'scoped'? variable_reference
    ;

argument_list は、1 ぀以䞊の 匕数コンマで区切っお構成されたす。 各匕数は、省略可胜な argument_name の埌に argument_valueで構成されたす。 argument_name を持぀ 匕数 は 名前付き匕数ず呌ばれたすが、 argument_name のない 匕数 は 䜍眮匕数です。

argument_value には、次のいずれかの圢匏を䜿甚できたす。

  • 匕数が倀パラメヌタヌずしお枡されるか、入力たたはref readonly参照パラメヌタヌに倉換され、(§12.6.4.2 および §12.6.2.3 で説明されおいる) によっお決定されたずおりに枡されるこずを瀺す匏。
  • キヌワヌド in 必芁に応じお scopedが続き、その埌に variable_reference (§9.5) が続き、匕数が入力パラメヌタヌ (§15.6.2.3.2) ずしお枡されるか、 ref readonly 参照パラメヌタヌ (§15.6.2.3.3) に倉換され、その埌、そのたた枡されるこずを瀺したす。 倉数を入力パラメヌタヌずしお枡す前に、倉数を確実に (§9.4) 割り圓おる必芁がありたす。 scopedの説明に぀いおは、§9.7.3 を参照しおください。
  • キヌワヌド ref 必芁に応じお、 scopedが続き、その埌に variable_reference (§9.5) が続き、匕数が参照パラメヌタヌ (§15.6.2.3.3) ずしお枡されるこずを瀺したす。 倉数を参照パラメヌタヌずしお枡す前に、倉数を確実に (§9.4) 割り圓おる必芁がありたす。 scopedの説明に぀いおは、§9.7.3 を参照しおください。
  • キヌワヌド out。必芁に応じお、 scopedが続き、 匕数 が出力パラメヌタヌ (§15.6.2.3.4) ずしお枡されるこずを瀺すvariable_reference (§9.5) が続きたす。 倉数が出力パラメヌタヌずしお枡される関数メンバヌ呌び出しの埌、倉数は確実に割り圓おられおいるず芋なされたす (§9.4)。 scopedの説明に぀いおは、§9.7.3 を参照しおください。
  • キヌワヌド out。必芁に応じお、 scopedが続き、新しいロヌカル倉数が宣蚀され、出力 パラメヌタヌ ( §15.6.2.3.4) ずしお枡されるこずを瀺すdeclaration_expression (§12.20) が続きたす。 新しく宣蚀された倉数は、関数メンバヌの呌び出しの埌に確実に割り圓おられおいる (§9.4) ず芋なされたす。 scopedの説明に぀いおは、§9.7.3 を参照しおください。

このフォヌムは、匕数の パラメヌタヌ受け枡しモヌド ( 倀、 入力、 参照、たたは 出力) をそれぞれ決定したす ( out キヌワヌドを䜿甚する䞡方のフォヌムでは、出力パッシング モヌドが䜿甚されたす)。 ただし、前述のように、倀枡しモヌドの匕数は、入力モヌドたたは ref readonly 参照受け枡しモヌドで 1 ぀に倉換される可胜性がありたす。

揮発性フィヌルド (§15.5.4) を入力、出力、たたは参照パラメヌタヌずしお枡すず、呌び出されたメ゜ッドではフィヌルドを揮発性ずしお扱うこずができないため、譊告が発生したす。

12.6.2.2 察応するパラメヌタヌ

匕数リスト内の匕数ごずに、呌び出される関数メンバヌたたはデリゲヌトに察応するパラメヌタヌが必芁です。

次に瀺すパラメヌタヌ リストは、次のように決定されたす。

  • クラスで定矩されおいる仮想メ゜ッドずむンデクサヌの堎合、パラメヌタヌ リストは、レシヌバヌの静的型から開始し、その基底クラスを怜玢するずきに怜出された関数メンバヌの最初の宣蚀たたはオヌバヌラむドから遞択されたす。 むンタヌフェむスで定矩された仮想メ゜ッドずむンデクサヌの堎合、パラメヌタヌ リストは、レシヌバヌの静的な型ず、関数メンバヌの宣蚀たたはオヌバヌラむドを含む盎接たたは間接的な基本むンタヌフェむスの䞭から、最も具䜓的なむンタヌフェむス (§19.4.10) にある関数メンバヌの宣蚀たたはオヌバヌラむドから遞択されたす。 このような最も具䜓的な䞀意のむンタヌフェむスが存圚しない堎合は、コンパむル時゚ラヌです。
  • 郚分メ゜ッドの堎合、定矩する郚分メ゜ッド宣蚀のパラメヌタヌ リストが䜿甚されたす。
  • 他のすべおの関数メンバヌずデリゲヌトには、䜿甚されるパラメヌタヌ リストが 1 ぀だけありたす。

匕数たたはパラメヌタヌの䜍眮は、匕数リストたたはパラメヌタヌ リストの前にある匕数たたはパラメヌタヌの数ずしお定矩されたす。

関数メンバヌ匕数の察応するパラメヌタヌは、次のように蚭定されたす。

  • 次のようなむンスタンス コンストラクタヌ、メ゜ッド、むンデクサヌ、およびデリゲヌトの argument_list 内の匕数。
    • パラメヌタヌがパラメヌタヌ コレクションであり、関数メンバヌが展開された圢匏で呌び出されない限り、パラメヌタヌ リスト内の同じ䜍眮にパラメヌタヌが発生する䜍眮匕数は、そのパラメヌタヌに察応したす。
    • 展開された圢匏で呌び出されたパラメヌタヌ コレクションを持぀関数メンバヌの䜍眮匕数。パラメヌタヌ リスト内のパラメヌタヌ コレクションの䜍眮以降に発生し、パラメヌタヌ コレクション内の芁玠に察応したす。
    • 名前付き匕数は、パラメヌタヌ リスト内の同じ名前のパラメヌタヌに察応したす。
    • むンデクサヌの堎合、set アクセサヌたたは init アクセサヌを呌び出すずき、代入挔算子の右オペランドずしお指定された匏は、set たたは init アクセサヌ宣蚀の暗黙的な value パラメヌタヌに察応したす。
  • プロパティの堎合、get アクセサヌを呌び出すずきに匕数はありたせん。 set アクセサヌたたは init アクセサヌを呌び出すずき、代入挔算子の右オペランドずしお指定された匏は、set たたは init アクセサヌ宣蚀の暗黙的な倀パラメヌタヌに察応したす。
  • ナヌザヌ定矩の単項挔算子 (倉換を含む) の堎合、単䞀オペランドは挔算子宣蚀の単䞀パラメヌタヌに察応したす。
  • ナヌザヌ定矩の二項挔算子の堎合、巊オペランドは最初のパラメヌタヌに察応し、右偎のオペランドは挔算子宣蚀の 2 番目のパラメヌタヌに察応したす。
  • 名前のない匕数は、䜍眮が指定されおいない名前付き匕数たたはパラメヌタヌ コレクションに察応する名前付き匕数の埌にある堎合、パラメヌタヌに察応したせん。

    泚意: void M(bool a = true, bool b = true, bool c = true);によっお M(c: false, valueB); が呌び出されるのを防ぎたす。 1 番目の匕数は範囲倖で䜿甚されたす (匕数は最初の䜍眮で䜿甚されたすが、 c ずいう名前のパラメヌタヌは 3 番目の䜍眮にありたす)、次の匕数に名前を付ける必芁がありたす。 ぀たり、末尟以倖の名前付き匕数は、名前ず䜍眮が同じ察応するパラメヌタヌを怜玢する堎合にのみ蚱可されたす。 泚釈

12.6.2.3 匕数リストの実行時評䟡

関数メンバヌ呌び出し (§12.6.6) の実行時に、匕数リストの匏たたは倉数参照は、次のように巊から右に順番に評䟡されたす。

  • 倀匕数の堎合、パラメヌタヌの受け枡しモヌドが倀の堎合

    • 匕数匏が評䟡され、察応するパラメヌタヌ型ぞの暗黙的な倉換 (§10.2) が実行されたす。 結果の倀は、関数メンバヌ呌び出しの value パラメヌタヌの初期倀になりたす。

    • それ以倖の堎合、パラメヌタヌの受け枡しモヌドは入力たたは ref 読み取り時です。 匕数が倉数参照であり、匕数の型ずパラメヌタヌの型の間に ID 倉換 (§10.2.2) が存圚する堎合、結果の栌玍堎所は関数メンバヌ呌び出しのパラメヌタヌによっお衚される栌玍堎所になりたす。 それ以倖の堎合は、察応するパラメヌタヌず同じ型でストレヌゞの堎所が䜜成されたす。 匕数匏が評䟡され、察応するパラメヌタヌ型ぞの暗黙的な倉換 (§10.2) が実行されたす。 結果の倀は、そのストレヌゞの堎所に栌玍されたす。 そのストレヌゞの堎所は、関数メンバヌ呌び出しの入力パラメヌタヌによっお衚されたす。

      䟋: 次の宣蚀ずメ゜ッド呌び出しを指定したす。

      static void M1(in int p1, ref readonly int p2) { ... }
      int i = 10;
      M1(i, i);         // i is passed as input and reference arguments
      M1(i + 5, i + 7); // both transformed to temporary arguments
      

      M1(i, i) メ゜ッドの呌び出しでは、i自䜓は、それぞれ入力ず参照匕数ずしお枡されたす。これは、倉数ずしお分類され、察応する入力パラメヌタヌず参照パラメヌタヌず同じ型intがあるためです。 M1(i + 5, i + 7) メ゜ッド呌び出しでは、2 ぀の名前のないint倉数が䜜成され、察応する匕数の倀で初期化され、それぞれ入力匕数ず参照匕数ずしお枡されたす。 §12.6.4.2 および §12.6.4.4を参照しおください。

      終了サンプル

  • 入力、出力、たたは参照匕数の堎合、倉数参照が評䟡され、結果の栌玍堎所が関数メンバヌ呌び出しのパラメヌタヌによっお衚される栌玍堎所になりたす。 入力たたは参照匕数の堎合、倉数はメ゜ッド呌び出しの時点で確実に割り圓おられたす。 倉数参照が出力匕数ずしお指定されおいる堎合、たたは reference_typeの配列芁玠である堎合は、配列の芁玠型がパラメヌタヌの型ず同じであるこずを確認するために実行時チェックが実行されたす。 このチェックが倱敗するず、System.ArrayTypeMismatchException がスロヌされたす。

泚: この実行時チェックは、配列の共倉性 (§17.6) が原因で必芁です。 泚釈

䟋: 次のコヌド䟋の内容:

class Test
{
    static void F(ref object x) {...}

    static void Main()
    {
        object[] a = new object[10];
        object[] b = new string[10];
        F(ref a[0]); // Ok
        F(ref b[1]); // ArrayTypeMismatchException
    }
}

F の 2 回目の呌び出しは、System.ArrayTypeMismatchException の実際の芁玠型が b であり、string ではないため、object がスロヌされる原因ずなりたす。

終了サンプル

メ゜ッド、むンデクサヌ、およびむンスタンス コンストラクタヌは、その右端のパラメヌタヌをパラメヌタヌ コレクションずしお宣蚀できたす (§15.6.2.4)。 このような関数メンバヌは、該圓する (§12.6.4.2) に応じお、通垞の圢匏たたは展開された圢匏で呌び出されたす。

  • パラメヌタヌ コレクションを持぀関数メンバヌが通垞の圢匏で呌び出される堎合、パラメヌタヌ コレクションに指定される匕数は、パラメヌタヌ コレクション型に暗黙的に倉換可胜な単䞀の匏 (§10.2) である必芁がありたす。 この堎合、パラメヌタヌ コレクションは倀パラメヌタヌずたったく同じように動䜜したす。
  • パラメヌタヌ コレクションを持぀関数メンバヌが展開圢匏で呌び出されるず、呌び出しでは、パラメヌタヌ コレクションに察しお 0 個以䞊の䜍眮匕数を指定する必芁がありたす。各匕数は、パラメヌタヌ コレクションの芁玠型に暗黙的に倉換可胜な匏 (§10.2) です。 この堎合、呌び出しは、匕数の数に察応する長さのパラメヌタヌ コレクション型のむンスタンスを䜜成し、指定された匕数倀を䜿甚しお配列むンスタンスの芁玠を初期化し、新しく䜜成された配列むンスタンスを実際の匕数ずしお䜿甚したす。

匕数リストの匏は、垞にテキスト順に評䟡されたす。

䟋: したがっお、この䟋では

class Test
{
    static void F(int x, int y = -1, int z = -2) =>
        Console.WriteLine($"x = {x}, y = {y}, z = {z}");

    static void Main()
    {
        int i = 0;
        F(i++, i++, i++);
        F(z: i++, x: i++);
    }
}

出力を生成したす。

x = 0, y = 1, z = 2
x = 4, y = -1, z = 3

終了サンプル

パラメヌタヌ コレクションを持぀関数メンバヌが展開された圢匏で少なくずも 1 ぀の展開された匕数で呌び出されるず、展開された匕数がcollection_expressionのcollection_elementであるかのように呌び出しが凊理されたす (§12.8.25)。 パラメヌタヌ コレクションの匕数がない堎合は、空のコレクションが枡されたす。枡された参照が新しく割り圓おられおいるか、既存の空のコレクションであるかは指定されおいたせん。

の䟋: 宣蚀が䞎えられた堎合

void F(int x, int y, params object[] args);

メ゜ッドの拡匵圢匏の次の呌び出し

F(10, 20, 30, 40);
F(10, 20, 1, "hello", 3.0);

正確に䞀臎する

F(10, 20, new object[] { 30, 40 });
F(10, 20, new object[] { 1, "hello", 3.0 });

終了サンプル

察応する省略可胜なパラメヌタヌを持぀関数メンバヌから匕数を省略するず、関数メンバヌ宣蚀の既定の匕数が暗黙的に枡されたす。 (これには、前述のように、ストレヌゞの堎所の䜜成が含たれる堎合がありたす)。

泚: これらは垞に䞀定であるため、その評䟡は残りの匕数の評䟡には圱響したせん。 泚釈

12.6.3 型掚論

12.6.3.1 党般

型匕数を指定せずにゞェネリック メ゜ッドを呌び出すず、 型掚論 プロセスは、呌び出しの型匕数を掚論しようずしたす。 型掚論が存圚するず、ゞェネリック メ゜ッドを呌び出すためにより䟿利な構文を䜿甚でき、プログラマは冗長な型情報を指定しないようにするこずができたす。

䟋:

class Chooser
{
    static Random rand = new Random();

    public static T Choose<T>(T first, T second) =>
        rand.Next(2) == 0 ? first : second;
}

class A
{
    static void M()
    {
        int i = Chooser.Choose(5, 213); // Calls Choose<int>
        string s = Chooser.Choose("apple", "banana"); // Calls Choose<string>
    }
}

型の掚論により、型匕数 int ず string は、匕数からメ゜ッドに察しお決定されたす。

終了サンプル

型掚論は、メ゜ッド呌び出し (§12.8.10.2) のバむンド時凊理の䞀郚ずしお発生し、呌び出しのオヌバヌロヌド解決ステップの前に行われたす。 メ゜ッドの呌び出しで特定のメ゜ッド グルヌプが指定されおいお、メ゜ッド呌び出しの䞀郚ずしお型匕数が指定されおいない堎合、メ゜ッド グルヌプ内の各ゞェネリック メ゜ッドに型掚論が適甚されたす。 型の掚論が成功した堎合、掚論された型匕数を䜿甚しお、埌続のオヌバヌロヌド解決のための匕数の型が決定されたす。 オヌバヌロヌド解決でゞェネリック メ゜ッドを呌び出すメ゜ッドずしお遞択した堎合、掚論された型匕数が呌び出しの型匕数ずしお䜿甚されたす。 特定のメ゜ッドの型掚論が倱敗した堎合、そのメ゜ッドはオヌバヌロヌドの解決に関䞎したせん。 型掚論自䜓が倱敗しおも、バむンド時゚ラヌは発生したせん。 ただし、オヌバヌロヌドの解決で該圓するメ゜ッドが芋぀からない堎合、バむンド時゚ラヌが発生するこずがよくありたす。

指定された各匕数がメ゜ッド内の 1 ぀のパラメヌタヌ (§12.6.2.2) に完党に察応しおいない堎合、たたは察応する匕数を持たない省略可胜でないパラメヌタヌがある堎合、掚論はすぐに倱敗したす。 それ以倖の堎合は、ゞェネリック メ゜ッドに次のシグネチャがあるずしたす。

Tₑ M<X₁...Xᵥ>(T₁ p₁ ... Tₓ pₓ)

フォヌム M(E₁ ...Eₓ) メ゜ッド呌び出しでは、型掚論のタスクは、呌び出し S₁...Sáµ¥ が有効になるように各型パラメヌタヌ X₁...Xáµ¥ に察しお、䞀意の型匕数 M<S₁...Sáµ¥>(E₁...Eₓ) を怜玢するこずです。

型掚論のプロセスをアルゎリズムずしお以䞋に説明したす。 準拠コンパむラは、すべおのケヌスで同じ結果に達した堎合に、代替アプロヌチを䜿甚しお実装できたす。

掚論のプロセス䞭、各型パラメヌタ Xáµ¢ は、特定の型 に察しおSᵢずなるか、境界䞀匏が関連付けられた未固定ずなりたす。各境界は、なんらかの T 型です。 最初に、 Xáµ¢ 各型倉数は、空の境界セットで固定解陀されたす。

型の掚論は段階的に行われたす。 各フェヌズでは、前のフェヌズの結果に基づいお、より倚くの型倉数の型匕数を掚論しようずしたす。 最初のフェヌズでは境界のいく぀かの初期掚論が行われたすが、2 番目のフェヌズでは型倉数が特定の型に修正され、さらに境界が掚論されたす。 2 番目のフェヌズは、䜕床も繰り返す必芁がある堎合がありたす。

泚: 型掚論は、メ゜ッド グルヌプの倉換 (§12.6.3.16) や䞀連の匏の最も䞀般的な型の怜玢 (§12.6.3.17) など、他のコンテキストでも䜿甚されたす。 泚釈

12.6.3.2 第 1 フェヌズ

Eᵢメ゜ッド匕数ごずに、から察応するパラメヌタヌ型Eᵢぞの入力型掚論 (Táµ¢) が行われたす。

12.6.3.3 第2フェヌズ

2 番目のフェヌズは次のように進みたす。

  • (§12.6.3.6) にXᵢしないすべおの固定されおいない型倉数は、すべおのXₑが固定されおいたす (§12.6.3.13)。
  • このような型倉数が存圚しない堎合、未固定の 型倉数 Xáµ¢ はすべお、次の条件が満たされる固定型 になりたす。
    • Xₑ に䟝存する型倉数 Xáµ¢ が少なくずも1぀ありたす
    • Xáµ¢ に空でない境界セットがある
  • そのような型倉数が存圚せず、 未解決 の型倉数がただ存圚する堎合、型掚論は倱敗したす。
  • それ以倖の堎合、 修正されおいない 型倉数がそれ以䞊存圚しない堎合、型の掚論は成功したす。
  • それ以倖の堎合、Eáµ¢ (Tⱌ) に固定されおいない型倉数が含たれおいるが、入力型 (§12.6.3.4) には含たれおいない、察応するパラメヌタヌ型Xₑを持぀すべおの 匕数に察しお、出力型掚論 (§12.6.3.8) が䜜成されたすEᵢ。Tⱌ その埌、2 番目のフェヌズが繰り返されたす。

12.6.3.4 入力型

がメ゜ッド グルヌプたたは暗黙の型指定された匿名関数であり、 がデリゲヌト型たたは匏ツリヌ型である堎合、 のすべおのパラメヌタヌ型は、型のの入力型 です。

Eがメ゜ッド グルヌプのアドレスであり、Tが関数ポむンタヌ型 (§24.3.3) の堎合、Tのすべおのパラメヌタヌ型は、E型を持぀Tの入力型になりたす。

泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

12.6.3.5 出力の皮類

がメ゜ッド グルヌプたたは匿名関数であり、 がデリゲヌト型たたは匏ツリヌ型である堎合、 の戻り倀の型は、型がのである 出力型になりたす。

Eがメ゜ッド グルヌプのアドレスであり、Tが関数ポむンタヌ型 (§24.3.3) の堎合、Tの戻り倀の型はE型を持぀Tの出力型になりたす。

泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

12.6.3.6 䟝存関係

unfixed 型倉数は Xᵢは、盎接 に䟝存し、匕数 に型 XₑEáµ¥ がある堎合、Táµ¥ 型倉数 Xₑは、 がある Eáµ¥ のTᵥで発生し、Xáµ¢ は、型 がある Eáµ¥ のTᵥで発生したす。

Xₑ が Xáµ¢ に盎接䟝存する堎合、たたは Xₑ が Xáµ¢ に盎接䟝存し、 Xáµ¢ が Xáµ¥ に䟝存する堎合、 Xáµ¥ はXₑ に䟝存したす。 したがっお、「はに䟝存する」は「はに盎接䟝存する」の掚移閉包であり、再垰的な閉包ではない。

12.6.3.7 入力型の掚論

入力型の掚論は、次のように型匏ETされたす。

  • Eが芁玠Eᵢを持぀collection_expressionで、Tが芁玠型TₑたたはTがnullable_value_typeでT0?芁玠型がTₑT0の堎合は、各Eᵢに察しお次のように指定したす。
    • Eᵢがexpression_elementの堎合、入力型の掚論はEáµ¢toTₑから行われたす。
    • Eᵢがむテレヌション型 (§13.9.5) Sᵢを持぀spread_elementである堎合、䞋限掚論 (§12.6.3.11) はSáµ¢toTₑから䜜成されたす。
  • Eが、アリティ ず芁玠がNされたタプル匏 (Eáµ¢) である堎合、 Tは、察応する芁玠型がNたたはTₑが null 蚱容倀型Tを持぀アリティ T0?を持぀タプル型であり、T0は察応する芁玠型Nを持぀アリティ Tₑを持぀タプル型であり、Eᵢごずに、EᵢからTₑぞの入力型掚論が行われたす。
  • Eが匿名関数であり、Tがデリゲヌト型たたは匏ツリヌ型の堎合、明瀺的なパラメヌタヌ型の掚論 (§12.6.3.9) はEtoTから行われ、明瀺的な戻り倀の型掚論はEからTに行われたす。
  • それ以倖の堎合、Eに型Uがあり、察応するパラメヌタヌが倀パラメヌタヌ (§15.6.2.2) の堎合、䞋限掚論 (§12.6.3.11) はUT行われたす。
  • それ以倖の堎合、Eに型Uがあり、察応するパラメヌタヌが参照パラメヌタヌ (§15.6.2.3.3) たたは出力パラメヌタヌ (§15.6.2.3.4) である堎合は、正確な掚論 (§12.6.3.10) U。
  • それ以倖の堎合、Eに型Uがあり、察応するパラメヌタヌが入力パラメヌタヌ (§15.6.2.3.2) で、Eが入力匕数である堎合は、正確な掚論 (§12.6.3.10) U。
  • それ以倖の堎合、Eに型Uがあり、察応するパラメヌタヌが入力パラメヌタヌ (§15.6.2.3.2) の堎合、䞋限掚論 (§12.6.3.11) はUT行われたす。
  • それ以倖の堎合、この匕数の掚論は行われたせん。

12.6.3.8 出力型の掚論

出力型の掚論は次のように型Eto型Tされたす。

  • Eが芁玠Eᵢを持぀collection_expressionで、Tが芁玠型TₑたたはTがnullable_value_typeでT0?芁玠型がTₑT0の堎合は、各Eᵢに察しお次のように指定したす。
    • Eᵢがexpression_elementの堎合、EᵢからTₑぞの出力型の掚論が行われたす。
    • Eᵢがspread_elementの堎合、Eᵢから掚論は行われたせん。
  • それ以倖の堎合、Eがアリティ Nず芁玠Eᵢを持぀タプル匏である堎合、 Tは、察応する芁玠型Tₑを持぀アリティNを持぀タプル型、たたはTが null 蚱容倀型T0?であり、T0は察応する芁玠型Tₑを持぀アリティNを持぀タプル型であり、Eᵢごずに出力型掚論がEᵢからTₑされたす。
  • TBDそれ以倖の堎合、Eが掚論された戻り倀の型U (§12.6.3.14) を持぀匿名関数であり、Tがデリゲヌト型たたは戻り倀の型がTₓ匏ツリヌ型である堎合、䞋䜍の掚論 (§12.6.3.11) はUtoTₓから行われたす。
  • それ以倖の堎合、 E がメ゜ッド グルヌプであり、 T がパラメヌタヌ型 T₁...Táµ¥ ず戻り倀の型 Tₓ を持぀デリゲヌト型たたは匏ツリヌ型であり、型 E による T₁...Táµ¥ のオヌバヌロヌド解決によっお戻り倀の型 U を持぀単䞀のメ゜ッドが生成されるず、 からU ぞの Tₓ が行われたす。
  • Eがメ゜ッド グルヌプのアドレスであり、Tが関数ポむンタヌ型 (§24.3.3) の堎合、パラメヌタヌ型T₁..Tₖず戻り倀の型Tₓを䜿甚し、型ET₁..Tₖのオヌバヌロヌド解決により、戻り倀の型Uを持぀ 1 ぀のメ゜ッドが生成され、からUぞのTₓが行われたす。

    泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

  • それ以倖の堎合、 E が型 U の匏である堎合、 䞋限掚論 が UからTたで行われたす。
  • それ以倖の堎合、掚論は行われたせん。

12.6.3.9 明瀺的なパラメヌタヌ型の掚論

明瀺的なパラメヌタ型掚論は、以䞋の方法で匏 E から型T行われたす。

  • Eがパラメヌタヌ型U₁...Uᵥ明瀺的に型指定された匿名関数で、Tがパラメヌタヌ型がV₁...Vᵥデリゲヌト型たたは匏ツリヌ型である堎合、各Uᵢに察しお、察応するに察しお正確な掚論 ()。Uáµ¢

12.6.3.10 正確な掚論

型 から型 UぞのVは、次のように行われたす。

  • V が 固定されおいないXáµ¢ の 1 ぀である堎合、 U は Xᵢの正確な境界のセットに远加されたす。

  • それ以倖の堎合、 V₁...Vₑ ず U₁...Uₑ のセットは、次のいずれかのケヌスが適甚されるかどうかを確認するこずによっお決定されたす。

    • V は配列型 V₁[...] であり、 U は同じランクの配列型 U₁[...] です
    • V は型 V₁? で、 U は型 U₁
    • V は構築された型 C<V₁...Vₑ> で、 U は構築された型 C<U₁...Uₑ>

    これらのケヌスのいずれかが該圓する堎合、各 に぀いお、察応する Uᵢぞの Váµ¢ を行いたす。

  • それ以倖の堎合、掚論は行われたせん。

12.6.3.11 䞋限掚論

型U型 の Vは、次のように行われたす。

  • V が 固定されおいないXáµ¢ の 1 ぀である堎合、 U は Xᵢの䞋限セットに远加されたす。
  • それ以倖の堎合、 V が型 V₁? で、 U が U₁? 型である堎合は、 U₁ から V₁ぞの䞋限掚論が行われたす。
  • それ以倖の堎合、 U₁...Uₑ ず V₁...Vₑ のセットは、次のいずれかのケヌスが適甚されるかどうかを確認するこずによっお決定されたす。
    • V は配列型 V₁[...] であり、 U は同じランクの配列型 U₁[...]です
    • V は、 IEnumerable<V₁>、 ICollection<V₁>、 IReadOnlyList<V₁>>、 IReadOnlyCollection<V₁> たたは IList<V₁> のいずれかであり、 U は 1 次元配列型 U₁[]
    • V は、構築された class、struct、interface、たたは delegate 型 C<V₁...Vₑ> であり、ナニヌクな型 C<U₁...Uₑ> が存圚したす。そしお、U たたは、U が型 parameterの堎合、その有効な基底クラスたたはその有効なむンタヌフェヌスセットのメンバヌが、inherits のいずれかず盎接たたは間接的に同䞀であるか、たたはC<U₁...Uₑ>を盎接たたは間接的に実装したす。
    • Vは関数ポむンタヌ型 (§24.3.3) delegate*<V₂..Vₖ, V₁>であり、delegate*<U₂..Uₖ, U₁>がUず同じで、delegate*<U₂..Uₖ, U₁>の呌び出し芏則がVず同じであり、Uの参照がVᵢず同じになるように、関数ポむンタヌ型Uᵢがありたす。

      泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

    • ("䞀意性" 制限は、むンタヌフェむスが C<T>{} class U: C<X>, C<Y>{}堎合、 U から C<T> ぞの掚論では、 U₁ が X たたは Y可胜性があるため、掚論は行われたせん。これらのケヌスのいずれかが適甚される堎合、次のように、各 Uáµ¢ から察応する Váµ¢ ぞの掚論が行われたす。
    • Uᵢが参照型であるこずが䞍明な堎合は、正確な掚論が行われたす。たたは、Uが関数ポむンタヌ型ではなく、Uᵢが参照型であるこずが䞍明な堎合、たたはUが関数ポむンタヌ型であり、Uᵢが関数ポむンタヌ型たたは参照型であるこずが䞍明な堎合は、正確な掚論が行われたす。

      泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

    • それ以倖の堎合、 U が配列型の堎合は、 䞋限掚論 が行われたす
    • それ以倖の堎合、 V が C<V₁...Vₑ> 堎合、掚論は i-thの C 型パラメヌタヌに䟝存したす。
      • 共倉の堎合、 䞋限掚論 が行われたす。
      • 反倉の堎合は、 䞊限掚論 が行われたす。
      • 䞍倉の堎合は、 正確な掚論 が行われたす。
    • それ以倖の堎合、 V が delegate*<V₂..Vₖ, V₁> 堎合、掚論は delegate*<V₂..Vₖ, V₁>の i 番目のパラメヌタヌに䟝存したす。
      • V1 の堎合:
        • 戻り倀が倀による堎合は、䞋限掚論が行われたす。
        • 戻り倀が参照である堎合は、正確な掚論が行われたす。
      • V2 の堎合..Vk:
        • パラメヌタヌが倀による堎合は、䞊限掚論が行われたす。
        • パラメヌタヌが参照である堎合は、正確な掚論が行われたす。

      泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

  • それ以倖の堎合、掚論は行われたせん。

12.6.3.12 䞊限掚論

型U型 の Vは、次のように行われたす。

  • V が 固定されおいないXáµ¢ の 1 ぀である堎合、 U は Xᵢの䞊限セットに远加されたす。
  • それ以倖の堎合、 V₁...Vₑ ず U₁...Uₑ のセットは、次のいずれかのケヌスが適甚されるかどうかを確認するこずによっお決定されたす。
    • U は配列型 U₁[...] であり、 V は同じランクの配列型 V₁[...]です
    • U は、 IEnumerable<Uₑ>、 ICollection<Uₑ>、 IReadOnlyList<Uₑ>、 IReadOnlyCollection<Uₑ> たたは IList<Uₑ> のいずれかであり、 V は 1 次元配列型 Vₑ[]
    • U は型 U1? で、 V は型 V1?
    • U は、クラス、構造䜓、むンタヌフェむス、たたはデリゲヌト型である C<U₁...Uₑ> であり、V は class, struct, interface 型たたは delegate 型であり、identical に盎接たたは間接的に関連し、inherits から掟生し、䞀意な型 C<V₁...Vₑ> を (盎接たたは間接的に) 実装しおいたす。
    • U は関数ポむンタヌ型 (§24.3.3) で、 delegate*<U₂..Uₖ, U₁> し、 V は delegate*<V₂..Vₖ, V₁>ず同じ関数ポむンタヌ型であり、 U の呌び出し芏則は Vず同じであり、 Uáµ¢ の参照は Vᵢず同じです。

      泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

    • ("䞀意性" 制限は、むンタヌフェむスが C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{}されるず、 C<U₁> から V<Q>ぞの掚論時に掚論が行われないこずを意味したす。掚論は、 U₁ から X<Q> たたは Y<Q>) に察しお行われたせん。これらのケヌスのいずれかが適甚される堎合、次のように、各 Uáµ¢ から察応する Váµ¢ ぞの掚論が行われたす。
    • Uが関数ポむンタヌ型ではなく、Uᵢが参照型であるこずが䞍明な堎合、たたはUが関数ポむンタヌ型であり、Uᵢが関数ポむンタヌ型たたは参照型であるこずが䞍明な堎合は、正確な掚論が行われたす。

      泚: 関数ポむンタヌ型関連のテキストは、安党でないコヌドでのみ適甚できたす。 泚釈

    • それ以倖の堎合、 V が配列型の堎合は、 䞊限掚論 が行われたす
    • それ以倖の堎合、 U が C<U₁...Uₑ> 堎合、掚論は i-thの C 型パラメヌタヌに䟝存したす。
      • 共倉の堎合は、 䞊限掚論 が行われたす。
      • 反倉の堎合、 䞋限掚論 が行われたす。
      • 䞍倉の堎合は、 正確な掚論 が行われたす。
  • それ以倖の堎合、 U が delegate*<U₂..Uₖ, U₁> 堎合、掚論は delegate*<U₂..Uₖ, U₁>の i 番目のパラメヌタヌに䟝存したす。
    • U1堎合:
      • 戻り倀が倀の堎合は、䞊限掚論が行われたす。
      • 戻り倀が参照である堎合は、正確な掚論が行われたす。
    • U2..Ukの堎合:
      • パラメヌタヌが倀による堎合は、䞋限掚論が行われたす。
      • パラメヌタヌが参照である堎合は、正確な掚論が行われたす。

    泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

  • それ以倖の堎合、掚論は行われたせん。

12.6.3.13 修正

䞀連の境界を持぀未固定型倉数 Xáµ¢ は、次のように固定されたす。

  • 候補の型のセットUₑは、匿名関数型でない型がある堎合、䞋限で匿名関数型が無芖されるXᵢの境界セット内のすべおの型のセットずしお開始されたす。
  • Xáµ¢ の各バむンドが順番に調べられ、 Xáµ¢ の正確なバむンドされた U ごずに、 Uₑ ず同じではないすべおの型 U が候補セットから削陀されたす。 Uすべおの型Xᵢの 各 lower bound Uₑ の堎合、 からの暗黙的倉換は、候補䞀匏から削陀U。 Xᵢすべおの型Uₑの各 upper bound U の堎合、 ぞの暗黙の倉換は、候補䞀匏から削陀U。
  • 残りの候補型 Uₑ 内に、他のすべおの候補型からの暗黙的な倉換がある䞀意の型 V がある堎合、 Xáµ¢ は Vに固定されたす。
  • それ以倖の堎合、型の掚論は倱敗したす。

12.6.3.14 掚論された戻り倀の型

F 匿名関数の掚論された戻り倀の型は、型の掚論ずオヌバヌロヌドの解決䞭に䜿甚されたす。 掚論された戻り倀の型は、すべおのパラメヌタヌ型が既知である匿名関数に察しおのみ決定できたす。これは、明瀺的に指定されおいるためか、匿名関数倉換によっお提䟛されるか、倖偎のゞェネリック メ゜ッド呌び出しで型掚論䞭に掚論されるためです。

掚定される有効な戻り倀の型 は、次のように決定されたす。

  • F の本䜓が型を持぀ 匏 である堎合、 F の掚定有効な戻り倀の型はその匏の型になりたす。
  • Fの本䜓がブロックであり、ブロックのreturn ステヌトメント内の匏のセットに最も䞀般的な型T (§12.6.3.17) がある堎合、掚定されるFの有効な戻り倀の型はT。
  • それ以倖の堎合、 Fの有効な戻り倀の型を掚論できたせん。

掚定される戻り倀の型 は、次のように決定されたす。

  • Fが非同期で、Fの本䜓が nothing (§12.2) ずしお分類された匏であるか、たたはreturnステヌトメントに匏がないブロックである堎合、掚論された戻り倀の型は«TaskType»されたす (§15.14.1)。
  • Fが非同期で、掚定された有効な戻り倀の型Tがある堎合、掚論される戻り倀の型は «TaskType»<T>»(§15.14.1) になりたす。
  • F が非同期で、掚定された有効な戻り倀の型が Tの堎合、掚論された戻り倀の型は Tです。
  • それ以倖の堎合は、 Fの戻り倀の型を掚論できたせん。

䟋: 匿名関数を含む型掚論の䟋ずしお、 Select クラスで宣蚀されおいる System.Linq.Enumerable 拡匵メ゜ッドを考えおみたしょう。

namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable<TResult> Select<TSource,TResult>(
            this IEnumerable<TSource> source,
            Func<TSource,TResult> selector)
        {
            foreach (TSource element in source)
            {
                yield return selector(element);
            }
        }
   }
}

System.Linq 名前空間が using namespace ディレクティブを䜿甚しおむンポヌトされ、 Customer型の Name プロパティを持぀クラス string が䞎えられた堎合、 Select メ゜ッドを䜿甚しお顧客の䞀芧の名前を遞択できたす。

List<Customer> customers = GetCustomerList();
IEnumerable<string> names = customers.Select(c => c.Name);

の拡匵メ゜ッド呌び出しSelectは、呌び出しを静的メ゜ッド呌び出しに曞き換えるこずによっお凊理されたす。

IEnumerable<string> names = Enumerable.Select(customers, c => c.Name);

型匕数は明瀺的に指定されおいないため、型匕数を掚論するために型掚論が䜿甚されたす。 たず、customers 匕数は゜ヌス パラメヌタヌに関連し、 TSource を Customerず掚論したす。 次に、前述の匿名関数型掚論プロセスを䜿甚しお、 c 型 Customerが䞎えられ、匏 c.Name はセレクタヌ パラメヌタヌの戻り倀の型に関連し、 TResultされる string を掚論する。 したがっお、呌び出しは

Sequence.Select<Customer,string>(customers, (Customer c) => c.Name)

そしお結果は IEnumerable<string> 型です。

次の䟋は、匿名関数型の掚論で、ゞェネリック メ゜ッド呌び出しの匕数間で型情報を "フロヌ" できるようにする方法を瀺しおいたす。 次のメ゜ッドず呌び出しを指定したす。

class A
{
    static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2)
    {
        return f2(f1(value));
    }

    static void M()
    {
        double hours = F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalHours);
    }
}

呌び出しの型掚論は次のように続行されたす。たず、匕数「1:15:30」は value パラメヌタヌに関連し、X が stringずしお掚論されたす。 次に、最初の匿名関数のパラメヌタヌ sには掚論された型 stringが䞎えられ、匏 TimeSpan.Parse(s) は f1の戻り倀の型ず関連しおおり、Y が System.TimeSpanであるこずが掚論されたす。 最埌に、2 番目の匿名関数のパラメヌタヌ t には掚論された型 System.TimeSpan が䞎えられ、匏 t.TotalHours は f2 の戻り倀の型に関連付けられ、 Z が double であるず掚論されたす。 したがっお、呌び出しの結果は double型になりたす。

終了サンプル

12.6.3.15 明瀺的な戻り倀の型掚論

明瀺的な戻り倀の型掚論は、次のように型E匏T行われたす。

  • Eが明瀺的な戻り倀の型Uᵣを持぀匿名関数で、Tがデリゲヌト型たたは戻り倀の型がVᵣ匏ツリヌ型である堎合、正確な掚論 (§12.6.3.10) はUáµ£Vᵣ行われたす。

12.6.3.16 メ゜ッド グルヌプの倉換のための型掚論

ゞェネリック メ゜ッドの呌び出しず同様に、ゞェネリック メ゜ッドを含むメ゜ッド グルヌプ M が特定のデリゲヌト型 D に倉換されるずきにも、型掚論が適甚されたす (§10.8)。 あるメ゜ッドが

Tₑ M<X₁...Xᵥ>(T₁ x₁ ... Tₑ xₑ)

ずデリゲヌト型 M に割り圓おられるメ゜ッドグルヌプ D ず等しくなり、継承型のタスクは、型匕数 S₁...Sáµ¥ を怜玢するため、匏は次のようになりたす。

M<S₁...Sᵥ>

は、ずの互換性 (D) になりたす。

ゞェネリック メ゜ッド呌び出しの型掚論アルゎリズムずは異なり、この堎合、匕数 型のみがあり、匕数 匏はありたせん。 特に、匿名関数がないため、掚論の耇数のフェヌズは必芁ありたせん。

代わりに、すべおの Xáµ¢ は、未固定ずしおみなされ、䞋限掚論は、各匕数型 のUₑ、察応するパラメヌタ型 D行われたす。 いずれかの Xáµ¢ で境界が芋぀からなかった堎合、型の掚論は倱敗したす。 それ以倖の堎合、すべおの Xáµ¢ は、型掚論の結果である察応する にSᵢ。

12.6.3.17 䞀連の匏の最も䞀般的な型を芋぀ける

堎合によっおは、䞀連の匏に぀いお共通の型を掚論する必芁がありたす。 特に、暗黙的に型指定された配列の芁玠型ず、 ブロック 本䜓を持぀匿名関数の戻り倀の型は、この方法で芋぀かりたす。

E₁...Eáµ¥ 䞀連の匏に最も䞀般的な型は、次のように決定されたす。

  • 新しい 修正されおいない 型倉数 X が導入されたした。
  • 各匏Eᵢ出力型の掚論 (§12.6.3.8) が、その匏からXに実行されたす。
  • X は 固定 (§12.6.3.13) であり、可胜であれば、結果の型が最も䞀般的な型です。
  • それ以倖の堎合、掚論は倱敗したす。

泚意: 盎感的にこの掚論は、 void M<X>(X x₁ ... X xáµ¥) を匕数ずしお Eáµ¢ メ゜ッドを呌び出し、 Xを掚論するこずず同じです。 泚釈

12.6.4 オヌバヌロヌドの解決

12.6.4.1 党般

オヌバヌロヌド解決は、匕数リストず候補関数メンバヌのセットを指定しお呌び出す最適な関数メンバヌを遞択するためのバむンディング時メカニズムです。 オヌバヌロヌド解決は、C# 内の次の個別のコンテキストで呌び出す関数メンバヌを遞択したす。

  • invocation_expression (§12.8.10) で名前が付けられたメ゜ッドの呌び出し。
  • object_creation_expression (§12.8.17.2) で名前が付けられたむンスタンス コンストラクタヌの呌び出し。
  • element_access (§12.8.12) を介したむンデクサヌ アクセサヌの呌び出し。
  • 匏 (§12.4.4 および §12.4.5) で参照される定矩枈み挔算子たたはナヌザヌ定矩挔算子の呌び出し。

これらの各コンテキストは、候補関数メンバヌのセットず、独自の方法で匕数のリストを定矩したす。 たずえば、メ゜ッド呌び出しの候補のセットには、オヌバヌラむドずしおマヌクされたメ゜ッド (§12.5) は含たれたせん。掟生クラス内のメ゜ッドが該圓する堎合(§12.8.10.2)、基底クラスのメ゜ッドは候補になりたせん。

各メ゜ッドには、メ゜ッド グルヌプを解決するプロセス䞭に䜿甚される型intのオヌバヌロヌド解決の優先順䜍がありたす。 既定では、その優先床は 0 です。 その倀は、 OverloadResolutionPriorityAttribute (§23.5.15) を䜿甚しお蚭定できたす。 メンバヌのオヌバヌロヌド解決の優先順䜍は、そのメンバヌの最小掟生宣蚀から取埗されたす。 オヌバヌロヌド解決の優先順䜍は、型メンバヌが実装できるむンタヌフェむス メンバヌから継承たたは掚論されず、むンタヌフェむス メンバヌ Miを実装するメンバヌ Mxが指定された堎合、Mxずオヌバヌロヌド解決の優先順䜍が異なるMi堎合は譊告は発行されたせん。

候補関数メンバヌず匕数リストが特定されるず、最適な関数メンバヌの遞択はすべおのケヌスで同じです。

  • たず、候補関数メンバヌのセットは、指定された匕数リスト (§12.6.4.2) に適甚できる関数メンバヌに瞮小されたす。 この瞮小セットが空の堎合、コンパむル時゚ラヌが発生したす。
  • 次に、候補メンバヌの瞮小されたセットは、型を宣蚀するこずによっおグルヌプ化されたす。 各グルヌプ内:
    • 候補関数のメンバヌは、オヌバヌロヌド解決の優先順䜍で䞊べ替えられたす。 メンバヌがオヌバヌラむドの堎合、オヌバヌロヌド解決の優先順䜍は、そのメンバヌの最䞋䜍の宣蚀から取埗されたす。
    • オヌバヌロヌド解決優先床が宣蚀型グルヌプ内で最も高い倀よりも䜎いメンバヌはすべお削陀されたす。
  • その埌、削枛されたグルヌプは、該圓する候補関数メンバヌの最終的なセットに再結合されたす。
  • 次に、適甚可胜な候補関数メンバヌのセットから最適な関数メンバヌが配眮されたす。 セットに含たれる関数メンバヌが 1 ぀だけの堎合、その関数メンバヌが最適な関数メンバヌになりたす。 それ以倖の堎合、各関数メンバヌが §12.6.4.3の ルヌルを䜿甚しお他のすべおの関数メンバヌず比范される堎合、特定の匕数リストに関しお他のすべおの関数メンバヌよりも優れおいる 1 ぀の関数メンバヌが最適な関数メンバヌになりたす。 他のすべおの関数メンバヌよりも優れた関数メンバヌが 1 ぀だけ存圚しない堎合、関数メンバヌの呌び出しはあいたいになり、バむンド時゚ラヌが発生したす。

次のサブクラりスは、甚語 適甚可胜な関数メンバヌ ず より優れた関数メンバヌの正確な意味を定矩したす。

12.6.4.2 該圓する関数メンバヌ

関数メンバヌは、次のすべおが真である堎合に、適甚可胜な関数メンバヌ が A 匕数リストに関しお適甚可胜であるず蚀われたす。

  • A の各匕数は、 §12.6.2.2で説明されおいるように、関数メンバヌ宣蚀のパラメヌタヌに察応し、最倧 1 ぀の匕数が各パラメヌタヌに察応し、匕数が察応しないパラメヌタヌは省略可胜なパラメヌタヌです。
  • Aの各匕数に぀いお、匕数のパラメヌタヌ受け枡しモヌドは、察応するパラメヌタヌのパラメヌタヌ受け枡しモヌドず同じです。そしお
    • 倀パラメヌタヌたたはパラメヌタヌ コレクションの堎合は、匕数匏から察応するパラメヌタヌの型ぞの暗黙的な倉換 (§10.2) が存圚したす。
    • 型が構造䜓型である参照パラメヌタヌの堎合は、匕数から察応するパラメヌタヌの型ぞの暗黙的な補間文字列ハンドラヌ倉換が存圚したす。
    • 参照パラメヌタヌたたは出力パラメヌタヌの堎合は、匕数匏の型 (存圚する堎合) ず察応するパラメヌタヌの型の間に ID 倉換がありたす。
    • 入力パラメヌタの堎合で、察応する匕数に in 修食子がある堎合、匕数匏の型 (存圚する堎合) ず察応するパラメヌタヌの型の間に ID 倉換があるか、
    • 匕数が in 修食子を省略した堎合、その匕数匏から察応するパラメヌタヌの型ぞの暗黙的な倉換 (§10.2) が存圚したす。
    • ref readonlyパラメヌタヌの堎合、察応する匕数がref修食子を省略するず、匕数匏から察応するパラメヌタヌの型ぞの暗黙的な倉換 (§10.2) が存圚したす。

パラメヌタヌ コレクションを含む関数メンバヌの堎合、関数メンバヌが䞊蚘の芏則で適甚できる堎合は、 通垞の圢匏で適甚可胜であるず蚀われたす。 パラメヌタヌ コレクションを含む関数メンバヌが通垞の圢匏で適甚できない堎合、関数メンバヌは代わりに、展開されたフォヌムで適甚できたす。

  • 展開されたフォヌムは、関数メンバヌ宣蚀のパラメヌタヌ コレクションを、コレクションの芁玠型の 0 個以䞊の倀パラメヌタヌに眮き換えお、匕数リスト内の匕数の数 A パラメヌタヌの合蚈数ず䞀臎したす。 A が関数メンバヌ宣蚀の固定パラメヌタヌの数よりも少ない匕数を持぀堎合、関数メンバヌの拡匵圢匏を構築できないため、適甚できたせん。
  • 次に瀺すいずれかの条件がA内の各匕数に圓おはたる堎合、展開された圢匏が適甚されたす。
    • 匕数のパラメヌタヌ受け枡しモヌドは、察応するパラメヌタヌのパラメヌタヌ受け枡しモヌドず同じです。
      • 固定倀パラメヌタヌたたは拡匵によっお䜜成された倀パラメヌタヌの堎合、匕数匏から察応するパラメヌタヌの型ぞの暗黙的な倉換 (§10.2) が存圚したす。又は
      • in、out、たたは ref パラメヌタヌの堎合、匕数匏の型は、察応するパラメヌタヌの型ず同じです。
    • 匕数のパラメヌタヌ受け枡しモヌドが value であり、察応するパラメヌタヌのパラメヌタヌ受け枡しモヌドが入力たたは ref readonlyであり、匕数匏から察応するパラメヌタヌの型ぞの暗黙的な倉換 (§10.2) が存圚したす。

匕数の型から入力パラメヌタヌのパラメヌタヌ型ぞの暗黙的な倉換が動的暗黙的な倉換 (§10.2.10) である堎合、結果は未定矩になりたす。

䟋: 次の宣蚀ずメ゜ッド呌び出しを指定したす。

public static void M1(int p1) { ... }
public static void M1(in int p1) { ... }
public static void M2(in int p1) { ... }
public static void Test()
{
    int i = 10; uint ui = 34U;

    M1(in i);   // M1(in int) is applicable
    M1(in ui);  // no exact type match, so M1(in int) is not applicable
    M1(i);      // M1(int) and M1(in int) are applicable
    M1(i + 5);  // M1(int) and M1(in int) are applicable
    M1(100u);   // no implicit conversion exists, so M1(int) is not applicable

    M2(in i);   // M2(in int) is applicable
    M2(i);      // M2(in int) is applicable
    M2(i + 5);  // M2(in int) is applicable
}

終了サンプル

  • 静的メ゜ッドは、メ゜ッド グルヌプが型を介しお simple_name たたは member_access からの結果である堎合にのみ適甚されたす。
  • むンスタンス メ゜ッドは、メ゜ッド グルヌプの結果が simple_name、倉数たたは倀を介した member_access たたは base_accessの堎合にのみ適甚されたす。
    • メ゜ッド グルヌプが simple_nameの結果である堎合、むンスタンス メ゜ッドは、 this アクセスが蚱可されおいる堎合にのみ適甚されたす§12.8.14。
  • §12.8.7.2 で説明されおいるように、メ゜ッド グルヌプがむンスタンスたたは型のいずれかを介しお実行できる member_accessから埗られる堎合、むンスタンスメ゜ッドず静的メ゜ッドの䞡方が適甚されたす。
  • 型匕数 (明瀺的に指定たたは掚論) が制玄を満たしおいないゞェネリック メ゜ッドは適甚できたせん。
  • メ゜ッド グルヌプ倉換のコンテキストでは、メ゜ッドの戻り倀の型からデリゲヌトの戻り倀の型ぞの ID 倉換 (§10.2.2) たたは暗黙的な参照倉換 (§10.2.8) が存圚する必芁がありたす。 それ以倖の堎合、候補メ゜ッドは適甚されたせん。

12.6.4.3 ベタヌ関数メンバヌ

より優れた関数メンバヌを決定するために、削陀された匕数リスト A は、元の匕数リストに衚瀺される順序で匕数匏自䜓だけを含み、out たたは ref 匕数を陀倖しお構築されたす。

各候補関数メンバヌのパラメヌタヌ リストは、次のように構築されたす。

  • 展開フォヌムは、関数メンバヌが展開フォヌムでのみ適甚された堎合に䜿甚されたす。
  • 察応する匕数のない省略可胜なパラメヌタヌは、パラメヌタヌ リストから削陀されたす
  • パラメヌタヌ リストから参照パラメヌタヌず出力パラメヌタヌが削陀される
  • パラメヌタヌは、匕数リスト内の察応する匕数ず同じ䜍眮に配眮されるように䞊べ替えられたす。

匕数匏のセット A ずパラメヌタ型 {E₁, E₂, 
, Eáµ¥} ず Mᵥを持぀2぀の適甚可胜な関数メンバヌ Mₓ ず {P₁, P₂, 
, Páµ¥} を含む匕数リスト {Q₁, Q₂, 
, Qáµ¥} が䞎えられた堎合、 Máµ¥ は よりも であるず定矩されたす。

  • 各匕数に察しお、 Eáµ¥ から Páµ¥ ぞの暗黙的な倉換は匿名関数型の倉換ではなく、

    • Máµ¥ は非ゞェネリック メ゜ッドたたは Máµ¥ 型パラメヌタヌが {X₁, X₂, 
, Xáµ¥} ゞェネリック メ゜ッドであり、各型パラメヌタヌに察しお、型匕数は匏たたは匿名関数型以倖の型から掚論されたす。
    • 少なくずも 1 ぀の匕数の堎合、 Eáµ¥ から Qáµ¥ ぞの暗黙的な倉換は匿名関数型倉換であるか、 Mₓ は型パラメヌタヌが {Y₁, Y₂, 
, Yáµ¥} ゞェネリック メ゜ッドであり、少なくずも 1 ぀の型パラメヌタヌに察しお、型匕数は匿名関数型から掚論されたす。
  • 各匕数に察しお、 Eáµ¥ から Qáµ¥ ぞの暗黙的な倉換は、 Eáµ¥ から Pᵥぞの暗黙的な倉換よりも適しおいたせん。

  • 少なくずも 1 ぀の匕数の堎合、 Eáµ¥ から Páµ¥ ぞの倉換は、 Eáµ¥ から Qᵥぞの倉換よりも優れおいたす。

パラメヌタヌ型シヌケンス {P₁, P₂, 
, Páµ¥} ず {Q₁, Q₂, 
, Qáµ¥} が等しい堎合 (぀たり、各 Páµ¢ が察応する Qᵢぞの ID 倉換を持぀堎合)、より適切な関数メンバヌを決定するために、次のタむブレヌク ルヌルが適甚されたす。

  • Máµ¢ が非ゞェネリック メ゜ッドであり、 Mₑ がゞェネリック メ゜ッドである堎合、 Máµ¢ は Mₑよりも優れおいたす。
  • それ以倖の堎合、Mᵢが通垞の圢匏で適甚され、Mₑにパラメヌタヌ コレクションがあり、展開されたフォヌムでのみ適甚できる堎合は、MₑよりもMᵢが適しおいたす。
  • それ以倖の堎合、䞡方のメ゜ッドにパラメヌタヌ コレクションがあり、展開されたフォヌムでのみ適甚できる堎合、およびMᵢのパラメヌタヌ コレクションの芁玠がMₑのパラメヌタヌ コレクションよりも少ない堎合は、MₑよりもMᵢが適しおいたす。
  • それ以倖の堎合、 Máµ¥ に Mₓよりも具䜓的なパラメヌタヌ型がある堎合は、 Máµ¥ は Mₓよりも優れおいたす。 {R1, R2, 
, Rn} ず {S1, S2, 
, Sn} は、Máµ¥ ず Mₓの未むンスタンス化および未展開のパラメヌタヌ型を衚したす。 Mᵥのパラメヌタ タむプは、各パラメヌタに぀いお Mₓ が Rx より具䜓的でなく、少なくずも 1 ぀のパラメヌタに぀いお Sx が Rx より具䜓的である堎合、 Sxのパラメヌタ タむプより具䜓的です。
    • 型パラメヌタヌは、型以倖のパラメヌタヌよりも具䜓的ではありたせん。
    • 構築された型が他の構築型同じ数の型匕数を持぀より具䜓的ずされるのは、少なくずも1぀の型匕数がより具䜓的で、か぀どの型匕数も他の型の察応する型匕数より具䜓的でないこずがない堎合です。
    • 配列型は、1 ぀目の芁玠型が 2 番目の芁玠型よりも具䜓的な堎合、(次元数が同じ) 別の配列型よりも具䜓的です。
  • それ以倖の堎合は、1 ぀のメンバヌが非リフト挔算子で、もう䞀方がリフトされた挔算子である堎合は、非リフト挔算子の方が適しおいたす。
  • どちらの関数メンバヌも良奜でなく、 Máµ¥ のすべおのパラメヌタヌに察応する匕数があるのに察し、既定の匕数は Mₓの少なくずも 1 ぀の省略可胜なパラメヌタヌに眮き換える必芁がある堎合、 Máµ¥ は Mₓよりも優れおいたす。
  • 少なくずも 1 ぀のパラメヌタヌ Máµ¥ で、 の察応するパラメヌタヌよりも 優れたパラメヌタヌパッシング遞択 (Mₓ)を䜿甚し、 Mₓ のどのパラメヌタヌも Mᵥよりも優れたパラメヌタヌ枡しの遞択肢を䜿甚しない堎合、 Máµ¥ は Mₓよりも優れおいたす。
  • それ以倖の堎合、䞡方のメ゜ッドにパラメヌタヌ コレクションがあり、展開されたフォヌムでのみ適甚できる堎合、同じ匕数のセットが䞡方のメ゜ッドのコレクション芁玠に察応し、次のいずれかの保留がある堎合、 Máµ¢ は Mₑ よりも優れおいたす。
    • 䞡方のパラメヌタヌ コレクションが span_typeではなく、 Máµ¢ のパラメヌタヌ コレクションからパラメヌタヌ コレクションぞの暗黙的な倉換が存圚したす。 Mₑ
    • Mᵢのパラメヌタヌ コレクションがSystem.ReadOnlySpan<Eáµ¢>され、Mₑのパラメヌタヌ コレクションがSystem.Span<Eₑ>され、Eáµ¢ からEₑ
    • Mᵢのパラメヌタヌ コレクションがSystem.ReadOnlySpan<Eáµ¢>たたはSystem.Span<Eáµ¢>であり、Mₑのパラメヌタヌ コレクションは、芁玠型がEₑされた配列たたは配列むンタヌフェむス型であり、Eᵢから ぞの ID 倉換が存圚したすEₑ
  • それ以倖の堎合、どの関数メンバヌもベタヌではありたせん。

delegate*は、void*よりも具䜓的です。

泚: これは安党でないコヌドにのみ適甚でき、 void* ず delegate* のオヌバヌロヌドを蚱可し、 & 挔算子が 2 ぀を区別できるようにしたす。 泚釈

12.6.4.4 パラメヌタヌ受け枡しモヌドの改善

次のように、2 ぀のパラメヌタヌの 1 ぀に倀枡しモヌドがある堎合、2 ぀のオヌバヌロヌドされたメ゜ッドで察応するパラメヌタヌがパラメヌタヌ枡しモヌドによっおのみ異なるこずがありたす。

public static void M1(int p1) { ... }
public static void M1(in int p1) { ... }

int i = 10;に基づいお、の §12.6.4.2によるず、呌び出し M1(i) ず M1(i + 5) に䞡方のオヌバヌロヌドが適甚されたす。 このような堎合、倀のパラメヌタ受け枡しモヌドを持぀メ゜ッドは、より良いパラメヌタ受け枡しモヌドの遞択肢になりたす。

泚: 入力、出力、たたは参照の受け枡しモヌドの匕数は、たったく同じパラメヌタヌの受け枡しモヌドにのみ䞀臎するので、このような遞択は必芁ありたせん。 泚釈

12.6.4.5 匏からの倉換の向䞊

C₁匏から型E に倉換する暗黙的な倉換 T₁ ず、 C₂ 匏から型 Eに倉換する暗黙的な倉換 T₂ を考えるず、 次のいずれかが保持されおいる堎合、 C₁ は よりも になりたす。

  • E は collection_expression であり、 C₁ は C₂ よりも匏からのコレクション倉換の方が優れおいたす (以䞋の定矩を参照)。
  • E は collection_expression ではなく、次のいずれかが保持されたす。
    • E は非定数 interpolated_string_expressionであり、 C₁ は暗黙的な補間文字列ハンドラヌ倉換であり、 T₁ は適甚可胜な補間文字列ハンドラヌ型であり、 C₂ は暗黙的な補間文字列ハンドラヌ倉換ではありたせん。
    • C₁ は function_type_conversion ではなく、 C₂ は function_type_conversionです。
    • E は T₂ ず完党には䞀臎せず、次のうち少なくずも 1 ぀が保持されたす。
      • E T₁ず完党に䞀臎し、EがT₂ず完党に䞀臎したせん (§12.6.4.6)。
      • C₁ は条件匏倉換ではなく、 C₂ は条件匏の倉換です。
      • E T₁ずT₂の䞡方たたは䞡方に完党に䞀臎し、T₁はT₂ (§12.6.4.7) よりも優れた倉換タヌゲットであり、C₁ずC₂は䞡方ずも条件匏倉換であるか、どちらも条件匏倉換でもありたせん。
        • V は関数ポむンタヌ型 delegate*<V₂..Vₖ, V₁> で、 U は関数ポむンタヌ型 delegate*<U₂..Uₖ, U₁>であり、 V の呌び出し芏則は Uず同じであり、 Váµ¢ の参照は Uᵢず同じです。

          泚: これは安党でないコヌドにのみ適甚されたす。 泚釈

      • Eはメ゜ッド グルヌプ (§12.2) であり、T₁は倉換C₁のメ゜ッド グルヌプの単䞀の最適なメ゜ッドず互換性があり (§21.4)、T₂は倉換C₂のメ゜ッド グルヌプの単䞀の最適なメ゜ッドず互換性がありたせん。

次の堎合:

  • E は、芁玠匏を含むコレクション匏です [EL₁, EL₂, ..., ELₙ]
  • T₁ ず T₂ はコレクション型です
  • E₁ は、次の芁玠の型です。 T₁
  • E₂ は、次の芁玠の型です。 T₂
  • CE₁ᵢ は、 ELáµ¢ から ぞの䞀連の倉換です。 E₁
  • CE₂ᵢ は、 ELáµ¢ から ぞの䞀連の倉換です。 E₂

E₁からE₂ぞの ID 倉換がある堎合、芁玠の倉換は互いに同じになりたす。 それ以倖の堎合、E₁ぞの芁玠倉換は、次の堎合にE₂ぞの芁玠倉換よりも優れおいたす。

  • すべおの ELᵢに぀いお、 CE₁ᵢ は少なくずも CE₂ᵢず同じくらい良いです。
  • CE₁ᵢが優れおいるiが少なくずも1぀ありたすCE₂ᵢ

それ以倖の堎合、どちらの芁玠倉換セットも他の芁玠よりも優れず、互いに優れおいるわけではありたせん。

ELᵢが拡散芁玠でない堎合は、匏からのより適切な倉換を䜿甚しお倉換比范が行われたす。 ELᵢがスプレッド芁玠の堎合は、スプレッド コレクションの芁玠型から、それぞれE₁たたはE₂ぞのより適切な倉換を䜿甚したす。

C₁は、次の堎合にC₂するよりも、匏からのコレクション倉換の方が優れおいたす。

  • T₁ずT₂はどちらもスパン型ではなく、T₁は暗黙的にT₂に倉換でき、T₂は暗黙的にT₁に倉換できたせん。
  • E₁には E₂ ぞの ID 倉換がありたせん。たた、E₁ ぞの芁玠倉換は、E₂ぞの芁玠倉換よりも優れおいたす。
  • E₁ には、 E₂ぞの ID 倉換があり、次のいずれかが保持されたす。
    • T₁がSystem.ReadOnlySpan<E₁>され、T₂がSystem.Span<E₂>
    • T₁がSystem.ReadOnlySpan<E₁>たたはSystem.Span<E₁>であり、T₂は芁玠型を持぀array_or_array_interfaceですE₂

それ以倖の堎合は、どちらのコレクション型も適しおいないので、結果はあいたいです。

䟋: 次の䟋は、配列初期化子ずコレクション匏の間のオヌバヌロヌド解決の違いを瀺しおいたす。

class C
{
    static void Generic<T>(Span<T> value) { }
    static void Generic<T>(T[] value) { }
    static void SpanDerived(Span<string> value) { }
    static void SpanDerived(object[] value) { }
    static void ArrayDerived(Span<object> value) { }
    static void ArrayDerived(string[] value) { }
    static void M()
    {
        // Array initializers
        Generic(new[] { "" });      // string[]
        SpanDerived(new[] { "" });  // ambiguous
        ArrayDerived(new[] { "" }); // string[]

        // Collection expressions
        Generic([""]);              // Span<string>
        SpanDerived([""]);          // Span<string>
        ArrayDerived([""]);         // ambiguous
    }
}

終了サンプル

12.6.4.6 厳密に䞀臎する匏

匏 E ず型 Tが、次のいずれかの条件を満たす堎合、EはT ず完党に䞀臎したす。

  • E には型 Sがあり、 S から T ぞの ID 倉換が存圚したす
  • E は匿名関数であり、T はデリゲヌト型 D たたは匏ツリヌ型 Expression<D> であり、次のいずれかが保持されたす。
    • Xのパラメヌタヌ リスト (E) のコンテキストでDの掚定戻り倀の型が存圚し、Xから戻り倀の型ぞの ID 倉換が存圚したすD
    • E は戻り倀のない async ラムダであり、D には非ゞェネリック «TaskType» である戻り倀の型がありたす
    • Eが非非同期で、Dが戻り倀の型Yを持぀か、Eが非同期でD戻り倀の型が«TaskType»<Y>(§15.14.1)、次のいずれかが保持されたす。
      • E の本䜓は、 Y ず完党に䞀臎する匏です
      • E の本䜓は、すべおの return ステヌトメントが Y ず完党に䞀臎する匏を返すブロックです。

12.6.4.7 コンバヌゞョンタヌゲットの向䞊

2 皮類の ず がある堎合、次のいずれかを満たす堎合には、 は よりも の 優れた倉換タヌゲットです。

  • T₁ から T₂ ぞの暗黙的な倉換が存圚し、 T₂ から T₁ ぞの暗黙的な倉換は存圚したせん
  • T₁ は «TaskType»<S₁>(§15.14.1)、 T₂ は «TaskType»<S₂>、 S₁ は S₂ より良い倉換先です。
  • T₁ は «TaskType»<S₁>(§15.14.1)、 T₂ は «TaskType»<S₂>、 T₁ は T₂ より専門的です。
  • T₁ は S₁ たたは S₁? で、 S₁ は笊号付き敎数型、 T₂ は S₂ たたは S₂? で、 S₂ は笊号なし敎数型です。 具䜓的には:
    • S₁ が sbyte であり、 S₂ が byte、 ushort、 uint、 nuint、たたは ulong
    • S₁ は short で、 S₂ は ushort、 uint、 nuint、たたは ulongです
    • S₁ は int であり、S₂ は uint、nuint、たたは ulong
    • S₁ が nint され、 S₂ が nuint たたは ulong
    • S₁ が long され、 S₂ が nuint たたは ulong

12.6.4.8 ゞェネリック クラスでのオヌバヌロヌド

泚: 宣蚀されおいるシグネチャは䞀意である必芁がありたすが、型匕数を眮換するず同じシグネチャになる可胜性がありたす (§8.6)。 このような状況では、オヌバヌロヌドの解決においお、元のシグネチャ型匕数の眮換前の䞭で最も具䜓的なものが遞択されたす存圚する堎合。それが存圚しない堎合には、゚ラヌが報告されたす§12.6.4.3。 泚釈

䟋: 次の䟋は、この芏則に埓っお有効で無効なオヌバヌロヌドを瀺しおいたす。

public interface I1<T> { ... }
public interface I2<T> { ... }

public abstract class G1<U>
{
    public abstract int F1(U u);           // Overload resolution for G<int>.F1
    public abstract int F1(int i);         // will pick non-generic

    public abstract void F2(I1<U> a);      // Valid overload
    public abstract void F2(I2<U> a);
}

abstract class G2<U,V>
{
    public abstract void F3(U u, V v);     // Valid, but overload resolution for
    public abstract void F3(V v, U u);     // G2<int,int>.F3 will fail

    public abstract void F4(U u, I1<V> v); // Valid, but overload resolution for
    public abstract void F4(I1<V> v, U u); // G2<I1<int>,int>.F4 will fail

    public abstract void F5(U u1, I1<V> v2);   // Valid overload
    public abstract void F5(V v1, U u2);

    public abstract void F6(ref U u);      // Valid overload
    public abstract void F6(out V v);
}

終了サンプル

12.6.5 動的メンバヌ呌び出しのコンパむル時チェック

動的にバむンドされた挔算のオヌバヌロヌド解決は実行時に行われたすが、コンパむル時にオヌバヌロヌドの遞択元ずなる関数メンバヌの䞀芧を把握できる堎合がありたす。

  • デリゲヌト呌び出し (§12.8.10.4) の堎合、リストは呌び出しの delegate_type ず同じパラメヌタヌ リストを持぀単䞀の関数メンバヌです
  • メ゜ッドの呌び出し (§12.8.10.2) の堎合、たたは静的な型が動的でない倀の堎合、メ゜ッド グルヌプ内のアクセス可胜なメ゜ッドのセットはコンパむル時に認識されたす。
  • オブゞェクト䜜成匏 (§12.8.17.2) の堎合、型内のアクセス可胜なコンストラクタヌのセットはコンパむル時に認識されたす。
  • むンデクサヌ アクセス (§12.8.12.5) の堎合、受信偎のアクセス可胜なむンデクサヌのセットはコンパむル時に認識されたす。

このような堎合は、既知の関数メンバヌセット内の各メンバヌに察しお制限付きコンパむル時チェックが実行され、実行時に呌び出されるこずがないこずがわかっおいるかどうかを確認したす。 各関数メンバヌ F に぀いお、倉曎されたパラメヌタヌず匕数のリストが構築されたす。

  • 最初に、 F がゞェネリック メ゜ッドであり、型匕数が指定された堎合は、パラメヌタヌ リストの型パラメヌタヌに眮き換えたす。 ただし、型匕数が指定されおいない堎合、このような眮換は行われたせん。
  • 次に、型が開いおいるすべおのパラメヌタヌ (぀たり、型パラメヌタヌが含たれおいたす。 §8.4.3 を参照) は、察応する匕数ず共に省略されたす。

F がチェックに合栌するには、次のすべおの条件を満たす必芁がありたす。

  • F の倉曎されたパラメヌタヌ リストは、 §12.6.4.2の倉曎された匕数リストに適甚されたす。
  • 倉曎されたパラメヌタヌ リスト内のすべおの構築された型は、その制玄を満たす (§8.4.5)。
  • 䞊蚘の手順で F の型パラメヌタヌが眮き換えられた堎合、それらの制玄は満たされたす。
  • F が静的メ゜ッドの堎合、メ゜ッド グルヌプは、コンパむル時にレシヌバヌが倉数たたは倀であるこずがわかっおいる member_access から発生したものではありたせん。
  • F がむンスタンス メ゜ッドの堎合、メ゜ッド グルヌプは、コンパむル時にレシヌバヌが型であるこずがわかっおいる member_access から発生したものではありたせん。

このテストに合栌した候補がない堎合は、コンパむル時゚ラヌが発生したす。

12.6.6 関数メンバヌの呌び出し

12.6.6.1 党般

このサブクラりズでは、特定の関数メンバヌを呌び出すために実行時に実行されるプロセスに぀いお説明したす。 バむンディング時プロセスは、呌び出す特定のメンバヌを既に決定しおいるこずを前提ずしおいたす。堎合によっおは、䞀連の候補関数メンバヌにオヌバヌロヌド解決を適甚したす。

呌び出しプロセスを蚘述するために、関数メンバヌは次の 2 ぀のカテゎリに分類されたす。

  • 静的関数メンバヌ。 これらは、静的メ゜ッド、静的プロパティ アクセサヌ、およびナヌザヌ定矩挔算子です。 静的関数メンバヌは垞に非仮想です。
  • むンスタンス関数メンバヌ。 これらは、むンスタンス メ゜ッド、むンスタンス コンストラクタヌ、むンスタンス プロパティ アクセサヌ、およびむンデクサヌ アクセサヌです。 むンスタンス関数メンバヌは非仮想たたは仮想であり、垞に特定のむンスタンスで呌び出されたす。 むンスタンスはむンスタンス匏によっお蚈算され、 this(§12.8.14) ずしお関数メンバヌ内でアクセスできるようになりたす。 むンスタンス コンストラクタヌの堎合、むンスタンス匏は新しく割り圓おられたオブゞェクトになりたす。

関数メンバヌ呌び出しの実行時凊理は、次の手順で構成されたす。ここで、 M は関数メンバヌであり、 M がむンスタンス メンバヌの堎合、 E はむンスタンス匏です。

  • Mが静的関数メンバヌの堎合:
    • 匕数リストは、 §12.6.2で説明されおいるように評䟡されたす。
    • M が呌び出されたす。
  • それ以倖の堎合、 E の型が倀型の Vであり、 M が Vで宣蚀たたはオヌバヌラむドされる堎合:
    • E が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。 むンスタンス コンストラクタヌの堎合、この評䟡は、新しいオブゞェクトにストレヌゞ (通垞は実行スタックから) を割り圓おるこずで構成されたす。 この堎合、 E は倉数ずしお分類されたす。
    • Eが倉数ずしお分類されおいない堎合、たたはVが読み取り専甚構造䜓型 (§16.2.2) ではなく、Mが読み取り専甚関数メンバヌ (§16.8.12) ではない堎合、Eは次のいずれかです。
      • 入力パラメヌタヌ (§15.6.2.3.2) たたは
      • readonly フィヌルド (§15.5.3) たたは
      • readonly参照倉数たたは戻り倀 (§9.7)、Eの型の䞀時ロヌカル倉数が䜜成され、Eの倀がその倉数に割り圓おられたす。 E は、その䞀時ロヌカル倉数ぞの参照ずしお再分類されたす。 䞀時倉数は、 this内で M ずしおアクセスできたすが、他の方法ではアクセスできたせん。 したがっお、E が曞き蟌み可胜な堎合に限り、呌び出し元は M が thisに加える倉曎を芳察するこずができたす。
    • 匕数リストは、 §12.6.2で説明されおいるように評䟡されたす。
    • M が呌び出されたす。 E によっお参照される倉数は、 thisによっお参照される倉数になりたす。
  • それ以倖の堎合:
    • E が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
    • 匕数リストは、 §12.6.2で説明されおいるように評䟡されたす。
    • E の型が value_typeの堎合、ボクシング倉換§10.2.9が実行され、 E が class_typeに倉換され、次の手順で E はその class_type であるず芋なされたす。 value_type が enum_typeの堎合、 class_type は System.Enum; それ以倖の堎合は System.ValueType。
    • E の倀が有効であるこずが確認されたす。 E の倀が null の堎合、 System.NullReferenceException がスロヌされ、それ以䞊の手順は実行されたせん。
    • 呌び出す関数メンバヌの実装が決定されたす。
      • E のバむンド時型がむンタヌフェむスの堎合、呌び出す関数メンバヌは、 M によっお参照されるむンスタンスのランタむム型によっお提䟛される E の実装です。 この関数メンバヌは、むンタヌフェむス マッピング 芏則 (§19.6.5) を適甚しお、Mによっお参照されるむンスタンスのランタむム型によっお提䟛されるEの実装を決定するこずによっお決定されたす。
      • それ以倖の堎合、 M が仮想関数メンバヌの堎合、呌び出す関数メンバヌは、 Mによっお参照されるむンスタンスのランタむム型によっお提䟛される E の実装です。 この関数メンバヌは、 によっお参照されるむンスタンスの実行時型に関しお、 M の最も掟生した実装を決定するための芏則Eを適甚するこずによっお決定されたす。
      • それ以倖の堎合、 M は非仮想関数メンバヌであり、呌び出す関数メンバヌは M それ自䜓 。
    • 䞊蚘の手順で決定した関数メンバヌの実装が呌び出されたす。 E によっお参照されるオブゞェクトが、このオブゞェクトによっお参照されるオブゞェクトになりたす。

泚:§12.2 は、察応する関数メンバヌ ( get アクセサヌたたは set アクセサヌ) を呌び出すものずしおプロパティ アクセスを分類したす。 䞊蚘のプロセスは、そのアクセサヌを呌び出すための手順に埓いたす。 泚釈

むンスタンス コンストラクタヌ (§12.8.17.2) の呌び出しの結果は、䜜成された倀です。 その他の関数メンバヌの呌び出しの結果は、その関数本䜓から返される倀(存圚する堎合)§13.10.5です。

12.6.6.2 ボックス化されたむンスタンスでの呌び出し

value_type に実装されおいる関数メンバヌは、次の状況で、その value_type のボックス化されたむンスタンスを介しお呌び出すこずができたす。

  • 関数メンバヌが型 class_type から継承されたメ゜ッドのオヌバヌラむドであり、その class_typeのむンスタンス匏を介しお呌び出される堎合。

    泚: class_type は垞に System.Object、 System.ValueType たたは System.Enumのいずれかになりたす。  泚釈

  • 関数メンバヌがむンタヌフェむス関数メンバヌの実装であり、 interface_typeのむンスタンス匏を介しお呌び出される堎合。
  • デリゲヌトを介しお関数メンバヌが呌び出されたずき。

このような状況では、ボックス化されたむンスタンスには value_typeの倉数が含たれおいるず芋なされ、この倉数は関数メンバヌ呌び出し内でこの倉数によっお参照される倉数になりたす。

泚: 特に、ボックス化されたむンスタンスで関数メンバヌが呌び出されるず、関数メンバヌがボックス化されたむンスタンスに含たれる倀を倉曎する可胜性があるこずを意味したす。 泚釈

12.7 分解

分解はコンパむル時の倉換であり、匏は個々の匏の タプル リテラル に眮き換えられたす。 分解は、割り圓おの分解で䜿甚されたす (§12.24.3)。

E以倖の型Sを持぀匏dynamicは、次のいずれかが保持されおいる堎合にタプル リテラルに分解できたす。

  • Eがタプル リテラルの堎合、分解の結果はそれ自䜓E匏になりたす。

  • それ以倖の堎合、Eにタプル型(T₁, 
, Tₙ)がある堎合、分解の結果は、(E.Item1, 
, E.Itemn)が 1 回だけ評䟡される以倖は、匏Eず意味的に同等になりたす。

  • それ以倖の堎合は、䞀意のむンスタンスたたは拡匵メ゜ッドがS.Deconstruct;n ≥ 2出力パラメヌタヌがあり、型がT₁にTₙされおいお、他のパラメヌタヌがない堎合は、E分解できたす。 分解の結果は、 E を次の擬䌌コヌドに眮き換えるこずず意味的に同等です。

    E.Deconstruct(out T1 v1, 
, out TN vn) andThen (v1, 
, vn);
    

    ここで、 andThen は、巊偎のオペランドを実行し、結果ずしお右オペランドを返す擬䌌 C# 挔算です。

    泚: andThen は、C および C++ のコンマ挔算子ず同じです。 泚釈

䞊蚘の保留 E を分解できない堎合は、コンパむル時゚ラヌになりたす。

泚: タプル リテラル の個々の芁玠のみが䜿甚されるコンテキストで分解を䜿甚する堎合 (分解割り圓おの䞀郚など)、タプル リテラル からのタプル倀の䜜成を明瀺的に蚱可したす。ただし、監芖可胜なセマンティクスは Eliding タプル (§8.3.11.2) で指定されおいるずおりに倉わりたせん。 泚釈

12.8 䞀次匏

12.8.1 党般

䞻な匏には、最も単玔な圢匏の匏が含たれたす。

primary_expression
    : literal
    | interpolated_string_expression
    | simple_name
    | parenthesized_expression
    | tuple_literal
    | member_access
    | null_conditional_member_access
    | invocation_expression
    | element_access
    | null_conditional_element_access
    | this_access
    | base_access
    | post_increment_expression
    | post_decrement_expression
    | null_forgiving_expression
    | array_creation_expression
    | object_creation_expression
    | delegate_creation_expression
    | anonymous_object_creation_expression
    | typeof_expression
    | sizeof_expression
    | checked_expression
    | unchecked_expression
    | default_value_expression
    | nameof_expression
    | anonymous_method_expression
    | pointer_member_access     // unsafe code support
    | pointer_element_access    // unsafe code support
    | stackalloc_expression
    | collection_expression
    ;

泚: この文法芏則は、ANTLR が凊理しない盞互巊再垰芏則 (primary_expression、 member_access、 invocation_expression、 element_access、 post_increment_expression、 post_decrement_expression、 null_forgiving_expression、 pointer_member_access 、 pointer_element_access) のセットの䞀郚であるため、ANTLR 察応ではありたせん。 暙準の手法を䜿甚しお文法を倉換し、盞互巊再垰を削陀できたす。 この暙準では、すべおの解析戊略で必芁ずされるわけではないため䟋えば、LALRパヌサヌでは必芁ありたせん、これを行うず構造や説明が難読化されるこずになりたす。 泚釈

pointer_member_access (§24.6.3) ず pointer_element_access (§24.6.4) は、安党でないコヌド (§24) でのみ䜿甚できたす。

12.8.2 リテラル

literal (§6.4.5) で構成される primary_expression は、倀ずしお分類されたす。

12.8.3 むンタヌポレヌト文字列匏

interpolated_string_expressionは 1 ぀以䞊の$文字で始たり、必芁に応じお@ (補間された逐語文字列の堎合) ず組み合わされ、その盎埌に"たたは"""スタむルの区切り蚘号内のテキストが続きたす。 匕甚笊で囲たれたテキスト内には、1 ぀以䞊の{文字ず}文字で区切られた 0 個以䞊の補間があり、それぞれ匏ず省略可胜な曞匏指定を囲みたす。 補間の䞀郚ではない匕甚笊で囲たれたテキスト (次に瀺す文法芏則 Interpolated_Regular_String_Mid、 Interpolated_Verbatim_String_Mid、 およびInterpolated_Raw_String_Mid によっお定矩されおいる) は、 補間文字列匏セグメントの䞀郚です。 そのため、匕甚笊で囲たれたテキストには、0 個以䞊の挿入文字列匏セグメントが含たれたす。 次の interpolated_string_expressionに぀いお考えおみたしょう。

$"val = {{{val,4:X}}}; 2 * val = {2 * val}."

これには、 "val = {"、 "}; 2 * val = "、および "."の挿入文字列匏セグメントが含たれたす。このセグメントの最初の芁玠は、次の文法で説明するオヌプン/クロヌズ ブレヌス ゚スケヌプ シヌケンスが存圚する芁玠です。 匕甚笊で囲たれたテキストには、補間 "{val,4:X}" ず "{2 * val}"も含たれたす。

interpolated_string_expressionには、次のいずれかの圢匏がありたす。regular (interpolated_regular_string_expression)、verbatim (interpolated_verbatim_string_expression)、raw (interpolated_raw_string_expression);構文的には䌌おいたすが、意味的には異なりたすが、察応する圢匏の文字列リテラル (§6.4.5.6)。

interpolated_string_expression
    : interpolated_regular_string_expression
    | interpolated_verbatim_string_expression
    | interpolated_raw_string_expression
    ;

// interpolated regular string expressions

interpolated_regular_string_expression
    : Interpolated_Regular_String_Start Interpolated_Regular_String_Mid?
      ('{' regular_interpolation '}' Interpolated_Regular_String_Mid?)*
      Interpolated_Regular_String_End
    ;

regular_interpolation
    : expression (',' interpolation_minimum_width)?
      Regular_Interpolation_Format?
    ;

interpolation_minimum_width
    : constant_expression
    ;

Interpolated_Regular_String_Start
    : '$"'
    ;

// the following three lexical rules are context sensitive, see details below

Interpolated_Regular_String_Mid
    : Interpolated_Regular_String_Element+
    ;

Regular_Interpolation_Format
    : ':' Interpolated_Regular_String_Element+
    ;

Interpolated_Regular_String_End
    : '"'
    ;

fragment Interpolated_Regular_String_Element
    : Interpolated_Regular_String_Character
    | Simple_Escape_Sequence
    | Hexadecimal_Escape_Sequence
    | Unicode_Escape_Sequence
    | Open_Brace_Escape_Sequence
    | Close_Brace_Escape_Sequence
    ;

fragment Interpolated_Regular_String_Character
    // Any character except " (U+0022), \\ (U+005C),
    // { (U+007B), and } (U+007D).
    : ~["\\{}]
    ;

// interpolated verbatim string expressions

interpolated_verbatim_string_expression
    : Interpolated_Verbatim_String_Start Interpolated_Verbatim_String_Mid?
      ('{' verbatim_interpolation '}' Interpolated_Verbatim_String_Mid?)*
      Interpolated_Verbatim_String_End
    ;

verbatim_interpolation
    : expression (',' interpolation_minimum_width)?
      Verbatim_Interpolation_Format?
    ;

Interpolated_Verbatim_String_Start
    : '$@"'
    | '@$"'
    ;

// the following three lexical rules are context sensitive, see details below

Interpolated_Verbatim_String_Mid
    : Interpolated_Verbatim_String_Element+
    ;

Verbatim_Interpolation_Format
    : ':' Interpolated_Verbatim_String_Element+
    ;

Interpolated_Verbatim_String_End
    : '"'
    ;

fragment Interpolated_Verbatim_String_Element
    : Interpolated_Verbatim_String_Character
    | Quote_Escape_Sequence
    | Open_Brace_Escape_Sequence
    | Close_Brace_Escape_Sequence
    ;

fragment Interpolated_Verbatim_String_Character
    : ~["{}]    // Any character except " (U+0022), { (U+007B) and } (U+007D)
    ;

// lexical fragments used by both regular and verbatim interpolated strings

fragment Open_Brace_Escape_Sequence
    : '{{'
    ;

fragment Close_Brace_Escape_Sequence
    : '}}'
    ;

// interpolated raw string expressions

interpolated_raw_string_expression
    : single_line_interpolated_raw_string_expression
    | multi_line_interpolated_raw_string_expression
    ;

single_line_interpolated_raw_string_expression
    : Interpolated_Raw_String_Start
        (Interpolated_Raw_String_Mid | raw_interpolation)+
        Interpolated_Raw_String_End
    ;

Interpolated_Raw_String_Prefix
    : '$'+
    ;

Interpolated_Raw_String_Start
    : Interpolated_Raw_String_Prefix  Raw_String_Literal_Delimiter
    ;

// the following two lexical rules are context sensitive, see details below

Interpolated_Raw_String_Mid
    : Raw_String_Literal_Content+
    ;

Interpolated_Raw_String_End
    : Raw_String_Literal_Delimiter
    ;

raw_interpolation
    : raw_interpolation_start expression
        (',' interpolation_minimum_width)? Raw_Interpolation_Format?
        raw_interpolation_end
    ;

raw_interpolation_start
    : '{'+
    ;

raw_interpolation_end
    : '}'+
    ;

// the following lexical rule is context sensitive, see details below

Raw_Interpolation_Format
    : ':' Interpolated_Raw_String_Character+
;

fragment Interpolated_Raw_String_Character
    // Any character except " (U+0022), \\ (U+005C),
    // { (U+007B), } (U+007D), and New_Line_Character.
    : ~["\\{}\u000D\u000A\u0085\u2028\u2029]
    ;

multi_line_interpolated_raw_string_expression
    : Interpolated_Raw_String_Start Whitespace* New_Line
      (Interpolated_Raw_String_Mid | raw_interpolation | New_Line)* New_Line
      Whitespace* Interpolated_Raw_String_End
    ;

䞊蚘で定矩した字句芏則の倚くは、次のように コンテキストに䟝存 したす。

芏則 コンテキスト芁件
むンタヌポレヌテッド_レギュラヌ_ストリング_ミッド Interpolated_Regular_String_Startの埌、次の補間の間、および察応する Interpolated_Regular_String_Endの前にのみ認識されたす。
Regular_Interpolation_Format regular_interpolation 内でのみ認識され、開始コロン (:) が䜕らかの括匧 (䞞かっこ/䞭かっこ/角かっこ) でネストされおいない堎合。
Interpolated_Regular_String_End Interpolated_Regular_String_Start の埌でのみ認識され、介入するトヌクンが、Interpolated_Regular_String_Mid たたは、このような補間内の任意の interpolated_regular_string_expression を含む、regular_interpolation の䞀郚になるこずができるトヌクンである堎合。
Interpolated_Verbatim_String_MidVerbatim_Interpolation_FormatInterpolated_Verbatim_String_End これら 3 ぀の芏則の認識は、䞊蚘の察応する最初の 3 ぀の芏則の認識に埓い、前述の 各芏則 が察応する 逐語 的芏則に眮き換えられたす。
Raw_Interpolation_FormatInterpolated_Raw_String_EndをInterpolated_Raw_String_Midする これら 3 ぀の芏則の認識は、䞊蚘の察応する最初の 3 ぀の芏則の認識に埓い、前述の 各芏則 が察応する 生 の芏則に眮き換えられたす。

泚: 䞊蚘の芏則は、定矩が蚀語内の他のトヌクンの定矩ず重耇する堎合、コンテキストに䟝存したす。 泚釈

泚意: 䞊蚘の文法は、コンテキストに䟝存する字句ルヌルのため、ANTLR 察応ではありたせん。 他の字句ゞェネレヌタヌず同様に、ANTLR はコンテキストに䟝存する字句芏則をサポヌトしたす。たずえば、 字句モヌドを䜿甚したすが、これは実装の詳现であるため、この仕様の䞀郚ではありたせん。 泚釈

interpolated_string_expressionは倀ずしお分類され、衚瀺されるコンテキストに応じお次のいずれかの方法で評䟡されたす。

  1. 代入たたはメ゜ッド呌び出し匕数のタヌゲットに型 stringがある堎合、匏は既定の補間文字列ハンドラヌ ( System.Runtime.CompilerServices.DefaultInterpolatedStringHandler) によっお凊理され、結果の型は string。
  2. 代入たたはメ゜ッド呌び出しの匕数のタヌゲットに型 System.IFormattable たたは System.FormattableStringがある堎合、文字列倀は挿入文字列から構成されたせん。 代わりに、 System.FormattableString のむンスタンスが䜜成されたす。
  3. 代入たたはメ゜ッド呌び出し匕数のタヌゲットにカスタム補間文字列ハンドラヌ (§23.5.11.1) 型がある堎合は、
  • 補間された文字列に補間が含たれおいる堎合、匏はタヌゲットの型が stringされたかのように凊理されたす。
  • それ以倖の堎合、匏はカスタム補間文字列ハンドラヌによっお凊理され、結果にはそのカスタム補間文字列ハンドラヌの型が含たれたす。

これらの芏則を次に瀺したす。

static void M(string s) { }
static void M(SomeInterpolatedStringHandler s) { }

int val = 255;
M($"no interpolations");// invokes M(string)
M($"{val}");            // invokes M(SomeInterpolatedStringHandler)
string s1 = $"{val}";   // default handler used, as target has type string
M(s1);                  // invokes M(string)
SomeInterpolatedStringHandler str2 = $"{val}";   // custom handler used
M(str2);                // invokes M(SomeInterpolatedStringHandler)

このサブクラスの残りの郚分では、既定の補間文字列ハンドラヌの動䜜のみが凊理されたす。 カスタム補間文字列ハンドラヌの宣蚀ず䜿甚に぀いおは、 §23.5.11.1 を参照しおください。

補間 (regular_interpolation、verbatim_interpolation、raw_interpolation) の意味は、Regular_Interpolation_Format、Verbatim_Interpolation_Format、たたはRaw_Interpolation_Formatで指定された圢匏に埓stringの皮類の既定の圢匏に埓っお、匏の倀をずしお曞匏蚭定するこずです。 曞匏蚭定された文字列は、interpolation_minimum_width(存圚する堎合) によっお倉曎され、該圓する堎合は、string に補間される最終的な が生成されたす。

interpolation_minimum_width では、 constant_expression は intぞの暗黙的な倉換を持぀必芁がありたす。 フィヌルドの幅 は、この constant_expression の絶察倀ずし、の配眮 は、この constant_expressionの倀による笊号正たたは負ずしたす。

  • フィヌルド幅の倀が曞匏蚭定された文字列の長さ以䞋の堎合、曞匏蚭定された文字列は倉曎されたせん。
  • それ以倖の堎合、曞匏蚭定された文字列の長さがフィヌルドの幅ず等しくなるように、空癜文字が埋め蟌たれたす。
    • 配眮が正の堎合、曞匏蚭定された文字列にパディングを远加するこずで右揃えになりたす。
    • それ以倖の堎合は、パディングを远加するこずで巊揃えにしたす。

挿入文字列匏は、各補間の曞匏指定を含む曞匏指定文字列リテラルずしお扱われたす。

曞匏指定文字列リテラルは次のように構築されたす。ここで、N は interpolated_string_expression内の補間数です。 曞匏指定文字列リテラルは、次の順序で構成されたす。

  • Interpolated_Regular_String_Start、Interpolated_Verbatim_String_Start、たたはInterpolated_Raw_String_Startの文字
  • Interpolated_Regular_String_Mid、Interpolated_Verbatim_String_Mid、たたはInterpolated_Raw_String_Midの文字 (存圚する堎合)
  • N ≥ 1からIぞの0各メンバヌの N-1 の堎合:
    • プレヌスホルダヌの仕様:
      • 巊䞭かっこ ({) 文字
      • I の 10 進衚珟
      • 次に、察応するregular_interpolation、verbatim_interpolation、たたはraw_interpolationにinterpolation_minimum_widthがある堎合は、コンマ (,) の埌にconstant_expressionの倀の 10 進衚珟が続きたす。
      • 察応するregular_interpolation、verbatim_interpolation、たたはraw_interpolationのRegular_Interpolation_Format、Verbatim_Interpolation_Format、たたはRaw_Interpolation_Formatの文字 (存圚する堎合)
      • 右䞭かっこ (}) 文字
    • 察応する補間の盎埌の Interpolated_Regular_String_Mid、 Interpolated_Verbatim_String_Mid、たたは Interpolated_Raw_String_Mid の文字 (存圚する堎合)
  • 最埌に、 Interpolated_Regular_String_End、 Interpolated_Verbatim_String_End、たたは Interpolated_Raw_String_Endの文字。

埌続の匕数は、補間から順番に匏です (存圚する堎合)。

interpolated_string_expression に耇数の補間が含たれおいる堎合、それらの補間の匏は巊から右のテキスト順で評䟡されたす。

䟋:

この䟋では、次の曞匏指定機胜を䜿甚したす。

  • 敎数を倧文字の 16 進数ずしお曞匏蚭定する X 曞匏指定。
  • string 倀の既定の圢匏は倀自䜓です。
  • 指定された最小フィヌルド幅内で右揃えするポゞティブ アラむメント倀、
  • 指定された最小フィヌルド幅内で巊揃えするネガティブ アラむメント倀、
  • interpolation_minimum_width に察しお定矩された定数、および
  • {{ ず }} は、それぞれ { および } ずしお曞匏蚭定されたす。

たずえば、以䞋のように指定したずしたす。

string text = "red";
int number = 14;
const int width = -4;

その埌、以䞋を実行したす。

補間された文字列匏 stringず同矩 倀
$"{text}" string.Format("{0}", text) "red"
$"{{text}}" string.Format("{{text}}) "{text}"
$"{ text , 4 }" string.Format("{0,4}", text) " red"
$"{ text , width }" string.Format("{0,-4}", text) "red "
$"{number:X}" string.Format("{0:X}", number) "E"
$"{text + '?'} {number % 3}" string.Format("{0} {1}", text + '?', number % 3) "red? 2"
$"{text + $"[{number}]"}" string.Format("{0}", text + string.Format("[{0}]", number)) "red[14]"
$"{(number==0?"Zero":"Non-zero")}" string.Format("{0}", (number==0?"Zero":"Non-zero")) "Non-zero"
$$""""{number}"""" string.Format("{{number}}") "{number}"
$$"""{{number}}""" string.Format("{0}", number) "14"
$$"""""{{{number}}}""""" string.Format("{{{0}}}", number) "{14}"

終了サンプル

定数補間文字列は、次を含むinterpolated_string_expressionです。

  • 補間なし、たたは
  • 匏s がstring型の定数匏であり、これらの補間にはinterpolation_minimum_width、Regular_Interpolation_Format、Verbatim_Interpolation_Format、たたはRaw_Interpolation_Format指定子がありたせん。

たずえば、$"Hello"、$"{cs1}、world!" (指定 const string cs1 = $"Hello";)、$"{"Hello"、" + $"world!"}"、および $"xxx{(true ? $"{"X"}" : $"{$"{"Y"}"}")}yyy" はすべお定数補間文字列です。 ただし、$"{123}" ず $"{"abc"}{123.45}" はありたせん。

わかりやすくするために、ISE ずいう甚語は、interpolated_string_expression挔算子ずバむナリ 挔算子で構成されるinterpolated_string_expressionたたは+を意味するために、この仕様党䜓で䜿甚されたす。

12.8.4 単玔な名前

simple_name は識別子で構成され、必芁に応じお型匕数リストが続きたす。

simple_name
    : identifier type_argument_list?
    ;

simple_name は、フォヌム I たたはフォヌム I<A₁, ..., Aₑ>のいずれかのものです。ここで、 I は 1 ぀の識別子であり、 I<A₁, ..., Aₑ> は省略可胜な type_argument_listです。 type_argument_list が指定されおいない堎合は、 e を 0 にするこずを怜蚎しおください。 simple_name は次のように評䟡、分類されたす。

  • eが 0 で、ロヌカル倉数宣蚀空間 (§7.2) 内に、ロヌカル倉数、パラメヌタヌ (砎棄パラメヌタヌ (§12.22.2) を陀く)、たたは名前Iの定数を盎接含むsimple_nameが衚瀺される堎合、simple_nameはそのロヌカル倉数、パラメヌタヌ、たたは定数を参照し、倉数たたは倀ずしお分類されたす。
  • e が 0 で、 simple_name がゞェネリック メ゜ッド宣蚀内に出珟するが、その method_declaration の 属性 倖にある堎合、その宣蚀に名前 Iを持぀型パラメヌタヌが含たれおいる堎合、 simple_name はその型パラメヌタヌを参照したす。
  • eが 0 で、メ゜ッド宣蚀たたはそのパラメヌタヌの属性のnameof匏内にsimple_nameが衚瀺され、その宣蚀に名前Iを持぀パラメヌタヌたたは型パラメヌタヌが含たれおいる堎合、simple_nameはそのパラメヌタヌたたは型パラメヌタヌを参照したす。
  • それ以倖の堎合は、各むンスタンス型 T (§15.3.2) に察しお、すぐに倖偎の型宣蚀のむンスタンス型から始たり、倖偎の各クラスたたは構造䜓宣蚀のむンスタンス型 (存圚する堎合) を続行したす。
    • Tの宣蚀にプラむマリ コンストラクタヌ パラメヌタヌIが含たれおおり、参照がTのclass_baseのargument_list内、たたはTのフィヌルド、プロパティ、たたはむベントの初期化子内で行われる堎合、結果はプラむマリ コンストラクタヌ パラメヌタヌ Iになりたす。
    • それ以倖の堎合、 e が 0 で、 T の宣蚀に名前 Iを持぀型パラメヌタヌが含たれおいる堎合、 simple_name はその型パラメヌタヌを参照したす。
    • それ以倖の堎合、 内で I 型匕数を甚いた T のメンバヌ参照 (e) が䞀臎を生じる堎合:
      • T が、すぐに囲むクラスたたは構造䜓型のむンスタンス型であり、怜玢で 1 ぀以䞊のメ゜ッドが識別される堎合、結果は、 thisのむンスタンス匏が関連付けられたメ゜ッド グルヌプになりたす。 型匕数リストが指定されおいる堎合は、ゞェネリック メ゜ッド (§12.8.10.2) の呌び出しで䜿甚されたす。
      • それ以倖の堎合、 T が盎接囲むクラスたたは構造䜓のむンスタンスの型であり、怜玢がむンスタンス メンバヌを識別し、参照がむンスタンス コンストラクタヌ、むンスタンス メ゜ッド、たたはむンスタンス アクセサヌの ブロック 内で発生する堎合 (§12.2.1)、結果は圢匏 のメンバヌ アクセス (this.I) ず同じになりたす。 これは、 e が 0 の堎合にのみ発生したす。
      • それ以倖の堎合、結果はフォヌム たたは T.Iのメンバヌ アクセス (T.I<A₁, ..., Aₑ>) ず同じです。
    • それ以倖の堎合、 T の宣蚀にプラむマリ コンストラクタヌ パラメヌタヌ Iが含たれおいる堎合、結果はプラむマリ コンストラクタヌ パラメヌタヌ Iになりたす。
  • それ以倖の堎合は、Nごずの名前空間に察しお、simple_name が存圚する名前空間から始たり、倖偎の各名前空間 (存圚する堎合) を続行し、グロヌバル名前空間で終わるたで、゚ンティティが芋぀かるたで、次のステップが評䟡されたす。
    • Nがグロヌバル名前空間の堎合、珟圚のcompilation_unitには最䞊䜍レベルのステヌトメント (§7.1.3) が含たれおおり、simple_nameの宣蚀は、生成された゚ントリ ポむント メ゜ッド (§7.1.3) のmethod_body (§15.6.1) 内で盎接発生したす。
      • アクセスが無効であり、コンパむラ時゚ラヌが生成されたす。

        泚: この芏則は、最䞊䜍レベルのステヌトメント内の䞀郚の simple_name の宣蚀が、同じ simple_nameを䜿甚しお参照されおいる堎合、グロヌバル宣蚀を非衚瀺にできるこずを意味したす。 泚釈

    • それ以倖の堎合、 e が 0 で、 I が N 内の名前空間の名前である堎合は、次のようになりたす。
      • simple_nameが発生する堎所がNの名前空間宣蚀で囲たれおおり、名前空間宣蚀に名前空間たたは型に名前を関連付けるextern_alias_directiveたたはIが含たれおいる堎合、たたはプログラム内のNの名前空間宣蚀に、名前を名前空間たたは型に関連付けるIが含たれおいる堎合は、 その埌、simple_nameがあいたいになり、コンパむル時゚ラヌが発生したす。
      • それ以倖の堎合、 simple_name は I の N ずいう名前の名前空間を参照したす。
    • それ以倖の堎合、 N に名前 I および e 型パラメヌタヌを持぀アクセス可胜な型が含たれおいる堎合は、次のようになりたす。
      • eがれロで、simple_nameが発生する堎所がNの名前空間宣蚀で囲たれおおり、名前空間宣蚀に名前空間たたは型に名前を関連付けるextern_alias_directiveたたはIが含たれおいる堎合、たたはプログラム内のNの名前空間宣蚀に名前空間たたは型に名前を関連付けるIが含たれおいる堎合 その埌、simple_nameがあいたいになり、コンパむル時゚ラヌが発生したす。
      • それ以倖の堎合、 namespace_or_type_name は、指定された型匕数で構築された型を参照したす。
    • それ以倖の堎合、simple_name が発生する堎所が N の名前空間宣蚀で囲たれおいる堎合:
      • eが 0 で、名前をむンポヌトされた名前空間たたは型に関連付けるextern_alias_directiveたたはIが名前空間宣蚀に含たれおいる堎合、たたはプログラム内のNの名前空間宣蚀に、むンポヌトされた名前空間たたは型に名前を関連付けるglobal_using_alias_directiveが含たれおいるI堎合、simple_nameはその名前空間たたは型を参照したす。
      • それ以倖の堎合、名前空間宣蚀のusing_namespace_directiveによっおむンポヌトされた名前空間、およびプログラム内のの名前空間宣蚀のglobal_using_namespace_directiveおよびglobal_using_static_directives によっおむンポヌトされた名前空間ず型宣蚀に、名前NIずe型パラメヌタヌを持぀型が 1 ぀だけ含たれおいる堎合、simple_nameは、指定された型匕数で構築された型を参照したす。
      • それ以倖の堎合、名前空間宣蚀のusing_namespace_directiveによっおむンポヌトされた名前空間、およびプログラム内のの名前空間宣蚀のglobal_using_namespace_directiveおよびglobal_using_static_directiveによっおむンポヌトされた名前空間ず型宣蚀に、名前NおよびIe型パラメヌタヌを持぀耇数の型が含たれおいる堎合、simple_nameはあいたいになり、コンパむル時゚ラヌが発生したす。

    泚: このステップ党䜓は、 namespace_or_type_name (§7.7) の凊理における察応するステップず完党に平行です。 泚釈

  • それ以倖の堎合、 e が 0 で、 I が _識別子である堎合、 simple_name は 単玔な砎棄であり、宣蚀匏 (§12.20) の圢匏です。
  • それ以倖の堎合、 simple_name は未定矩であり、コンパむル時゚ラヌが発生したす。

12.8.5 括匧で囲たれた匏

括匧で囲たれた匏は、括匧で囲われた匏で構成されたす。

parenthesized_expression
    : '(' expression ')'
    ;

parenthesized_expression は、括匧内の匏を評䟡するこずで評䟡されたす。 かっこ内の 匏 が名前空間たたは型を瀺しおいる堎合は、コンパむル時゚ラヌが発生したす。 それ以倖の堎合、parenthesized_expression の結果が、含たれる匏の評䟡の結果ずなりたす。

12.8.6 タプル リテラル

tuple_literalはタプルを衚し、かっこで囲たれた 2 ぀以䞊のコンマ区切り匏ず必芁に応じお名前付き匏で構成されたす。

tuple_literal
    : '(' tuple_element (',' tuple_element)+ ')'
    ;

tuple_element
    : (identifier ':')? expression
    ;

tuple_literalはタプル (§12.2.1) ずしお分類されたす。

タプル リテラルは、各芁玠匏が型Eáµ¢Tᵢ堎合にのみ型を持ちたす。 この型はタプル リテラルず同じアリティのタプル型であり、各芁玠は次のように指定されたす。

  • 察応する䜍眮のタプル芁玠に芁玠名 Iᵢがある堎合、タプル型芁玠は Táµ¢ Iᵢ。
  • それ以倖の堎合、EᵢがIᵢ圢匏たたはE.Iᵢ圢匏たたはE?.Iᵢの堎合(Iᵢが識別子である堎合)、タプル型芁玠は、次のいずれかが保持Táµ¢ Iᵢ。
    • タプル リテラルの別の芁玠に芁玠名 Iᵢがありたす。
    • 芁玠名のない別のタプル芁玠には、 Iáµ¢ たたは E.Iáµ¢ たたは E?.Iᵢ圢匏のタプル芁玠匏がありたす。
    • Iáµ¢ はフォヌム ItemXです。ここで、 X はタプル芁玠の䜍眮を衚す可胜性のある先頭にれロを付けずに 10 進数字のシヌケンスであり、 X は芁玠の䜍眮を衚したせん。
  • それ以倖の堎合、タプル型芁玠は Tᵢです。

タプル倀は、次の堎合にタプル リテラルから取埗できたす。

  • これは倉換の察象 (§10.2.13) であり、倉換は本質的に持぀可胜性のある任意の型を眮き換えたす。
  • これは分解割り圓おのタヌゲットです (§12.24.3)。たたは
  • 倀 (§12.2.2)) ずしお再分類されたす。

䟋:

(short, long) x = (1, 2L); // literal has a type replaced by implicit conversion
var y = (1, 2L);           // y has type (int, long)

これら 2 ぀の䟋は、䞊蚘の最初のケヌスでの修食の目的を瀺しおいたす。これにより、暗黙的な定数倉換が可胜になりたす (§10.2.11)。 タプル リテラルの型は (int, long)。 intからshortぞの暗黙的な倉換はありたせんが、定数1から short ぞの倉換がありたす。 最初の䟋では、タプル リテラルの固有の型を眮き換える暗黙的な倉換が含たれたす。 暗黙的な倉換を䌎わない 2 番目の䟋では、タプル リテラルは固有の型に基づいお倀ずしお再分類されたす。

(long l, string) t1 = (l: 1, null); // literal has no type, use implicit conversion
var t2 = (i: 2, "Two");             // (int i, string)
var t3 = (i: 3, null);              // Error: no type

3 ぀の宣蚀ステヌトメントのこの䟋では、初期化タプル リテラル自䜓はすべお有効です。 t1の堎合、暗黙的なタプル倉換は、 1 から long ぞの暗黙的な倉換ず、 null から stringぞの暗黙的な倉換に䟝存したす。 2 番目のタプル リテラルには (int i, string)型があるため、その型の倀ずしお再分類できたす。 䞀方、 t3の宣蚀ぱラヌです。タプル リテラルには型がないため、2 番目の芁玠には型がなく、倀ずしお再分類できないため、倱敗したす。

if ((x, y).Equals((1, 2))) { ... };

この䟋は、タプルリテラルがメ゜ッド呌び出しの唯䞀の匕数である堎合に、タプルが耇数のかっこの局に぀ながる可胜性があるこずを瀺しおいたす。

終了サンプル

12.8.7 メンバヌ アクセス

12.8.7.1 党般

member_access は、primary_expression、predefined_type たたは qualified_alias_member で構成され、「.」トヌクン、識別子が続き、任意で、type_argument_list が続きたす。

member_access
    : primary_expression '.' identifier type_argument_list?
    | predefined_type '.' identifier type_argument_list?
    | qualified_alias_member '.' identifier type_argument_list?
    ;

predefined_type
    : 'bool' | 'byte' | 'char' | 'decimal' | 'double' | 'float' | 'int'
    | 'long' | 'object' | 'sbyte' | 'short' | 'string' | 'uint' | 'ulong'
    | 'ushort'
    ;

qualified_alias_member生産は §14.9 で定矩されおいたす。

member_access は、E.I から、たたは E.I<A₁, ..., Aₑ> からのいずれかで、E は、primary_expression、predefined_type たたは qualified_alias_member で、I は、単䞀識別子で、<A₁, ..., Aₑ> は任意の type_argument_list です。 type_argument_list が指定されおいない堎合は、 e を 0 にするこずを怜蚎しおください。

型 がある primary_expression の dynamic は、動的にバむンドされたす (§12.3.3)。 この堎合、メンバヌ アクセスは型 dynamicのプロパティ アクセスずしお分類されたす。 member_access の意味を刀断するための以䞋の芏則は、 primary_expressionのコンパむル時の型ではなく実行時の型を䜿甚しお実行時に適甚されたす。 このランタむム分類が、メ゜ッドグルヌプに぀ながる堎合、メンバヌ アクセスは、invocation_expression の primary_expression になりたす。

member_access は次のように評䟡され、分類されたす。

  • e が 0 で、 E が名前空間であり、 E に名前 Iを持぀入れ子になった名前空間が含たれおいる堎合、結果はその名前空間になりたす。
  • それ以倖の堎合、 E が名前空間であり、 E に名前 I および K 型パラメヌタヌを持぀アクセス可胜な型が含たれおいる堎合、その型は指定された型匕数で構築されたす。
  • E が型ずしお分類され、 E が型パラメヌタでなく、 の I ず E 型パラメヌタのメンバ怜玢 (K) で䞀臎が生成される堎合、 E.I は次のように評䟡、分類されたす。

    泚: このようなメンバヌ怜玢の結果がメ゜ッド グルヌプで、 K が 0 の堎合、メ゜ッド グルヌプには型パラメヌタヌを持぀メ゜ッドを含めるこずができたす。 これにより、このようなメ゜ッドを型匕数の掚論ず芋なすこずができたす。 泚釈

    • I が型を識別する堎合、結果は、指定された型匕数を䜿甚しお構築された型になりたす。
    • I が 1 ぀以䞊のメ゜ッドを識別する堎合、結果はむンスタンス匏が関連付けられおいないメ゜ッド グルヌプになりたす。
    • I が静的プロパティを識別する堎合、結果は、関連付けられたむンスタンス匏のないプロパティ アクセスになりたす。
    • I が静的フィヌルドを識別する堎合:
      • フィヌルドが読み取り専甚で、フィヌルドが宣蚀されおいるクラスたたは構造䜓の静的コンストラクタヌの倖郚で参照が発生した堎合、結果は倀(぀たり、 Iにおける静的フィヌルド E の倀) になりたす。
      • それ以倖の堎合、結果は倉数、぀たり Iにおける静的フィヌルド E です。
    • I が静的むベントを識別する堎合:
      • むベントが宣蚀されおいるクラスたたは構造䜓内で参照が発生し、むベントが event_accessor_declarations (§15.8.1) なしで宣蚀された堎合、 E.I は、 I が静的フィヌルドであるかのように正確に凊理されたす。
      • それ以倖の堎合、結果はむンスタンス匏が関連付けられおいないむベント アクセスであるこずになりたす。
    • I が定数を識別する堎合、結果は倀、぀たりその定数の倀になりたす。
    • I が列挙メンバヌを識別する堎合、結果は倀 (぀たり、その列挙メンバヌの倀) になりたす。
    • それ以倖の堎合、 E.I は無効なメンバヌ怜玢であり、コンパむル時゚ラヌが発生したす。
  • E がプロパティ アクセス、むンデクサヌ アクセス、倉数、たたは倀であり、その型が T であり、 内の I ず T 型匕数のメンバヌ怜玢 (K) で䞀臎が生成された堎合、 E.I は次のように評䟡され、分類されたす。
    • 最初に、 E がプロパティたたはむンデクサヌ アクセスの堎合、プロパティたたはむンデクサヌ アクセスの倀 (§12.2.2) が取埗され、E が倀ずしお再分類されたす。
    • I が 1 ぀以䞊のメ゜ッドを識別する堎合、結果は、関連付けられたむンスタンス匏 E を持぀メ゜ッド グルヌプになりたす。
    • I がむンスタンス プロパティを識別する堎合、結果は、 E の関連付けられたむンスタンス匏ず、プロパティの型である関連付けられた型を持぀プロパティ アクセスになりたす。 T がクラス型の堎合、関連付けられおいる型は、 Tで始たり、その基底クラスを怜玢するずきに芋぀かったプロパティの最初の宣蚀たたはオヌバヌラむドから遞択されたす。 Tがむンタヌフェむス型の堎合、関連付けられた型は、Tおよびその盎接たたは間接的な基本むンタヌフェむスの䞭から、最も具䜓的な (§19.4.10) むンタヌフェむスで芋぀かったプロパティの宣蚀たたはオヌバヌラむドから遞択されたす。 このような䞀意の型が存圚しない堎合は、コンパむル時゚ラヌです。
    • T が class_type で、 I がその class_typeのむンスタンス フィヌルドを識別する堎合:
      • E の倀が null の堎合、System.NullReferenceException がスロヌされたす。
      • それ以倖の堎合、フィヌルドが読み取り専甚で、そのフィヌルドが宣蚀されおいるクラスのむンスタンス コンストラクタヌの倖郚で参照が発生した堎合、結果は倀になりたす。぀たり、 Iによっお参照されるオブゞェクト内のフィヌルド E の倀です。
      • それ以倖の堎合、結果は倉数、぀たり、 I によっお参照されるオブゞェクト内のフィヌルド E です。
    • T が struct_type で、 I がその struct_typeのむンスタンス フィヌルドを識別する堎合:
      • E が倀である堎合、たたはフィヌルドが読み取り専甚で、そのフィヌルドが宣蚀されおいる構造䜓のむンスタンス コンストラクタヌの倖郚で参照が発生した堎合、結果は倀になりたす。぀たり、 Iによっお指定された構造䜓むンスタンス内のフィヌルド E の倀になりたす。
      • それ以倖の堎合、結果は倉数になりたす。぀たり、 Iによっお指定された構造䜓むンスタンス内のフィヌルド E です。
    • I がむンスタンス むベントを識別する堎合:
      • むベントが宣蚀されおいるクラスたたは構造䜓内で参照が発生し、event_accessor_declarations (§15.8.1) なしでむベントが宣蚀され、か぀参照がa +=挔算子たたは-=挔算子の巊偎ずしお発生しない堎合、E.IはたるでIがむンスタンスフィヌルドであるかのように正確に凊理されたす。
      • それ以倖の堎合、結果は、 Eのむンスタンス匏が関連付けられたむベント アクセスになりたす。
  • それ以倖の堎合は、 E.I を拡匵メ゜ッド呌び出しずしお凊理したす§12.8.10.3。 これが倱敗した堎合、 E.I は無効なメンバヌ怜玢であり、バむンド時゚ラヌが発生したす。

12.8.7.2 同じ単玔な名前ず型名

フォヌム E.Iのメンバヌ アクセスでは、Eが単䞀の識別子であり、simple_nameずしおのEの意味 (§12.8.4) が定数、フィヌルド、プロパティ、ロヌカル倉数、たたはパラメヌタヌであり、type_nameずしおのEの意味 (§7.7.1) ず同じ型である堎合は、Eの䞡方の意味が蚱可されたす。 E.I のメンバヌ怜玢は、どちらの堎合も I が必ず型 E のメンバヌになるので、決しお曖昧にはなりたせん。 ぀たり、この芏則は、コンパむル時゚ラヌが発生した E の静的メンバヌず入れ子になった型ぞのアクセスを蚱可するだけです。

䟋:

struct Color
{
    public static readonly Color White = new Color(...);
    public static readonly Color Black = new Color(...);
    public Color Complement() => new Color(...);
}

class A
{
    public «Color» Color;              // Field Color of type Color

    void F()
    {
        Color = «Color».Black;         // Refers to Color.Black static member
        Color = Color.Complement();  // Invokes Complement() on Color field
    }

    static void G()
    {
        «Color» c = «Color».White;       // Refers to Color.White static member
    }
}

説明目的でのみ、A クラス内における Color 識別子のうち、Color 型を参照するものは «...»で区切られ、Color フィヌルドを参照するものは区切られたせん。

終了サンプル

プラむマリ コンストラクタヌ (§15.11.6) に関しお、䞊蚘の芏則は、むンスタンス メンバヌ内の識別子を型参照ずしお扱うか、プラむマリ コンストラクタヌ パラメヌタヌ参照ずしお扱うかに圱響したす。これは、パラメヌタヌを倖偎の型の状態にキャプチャしたす。 " E.I のメンバヌ参照があいたいになるこずはありたせんが"、参照によっおメンバヌ グルヌプが生成される堎合でも、メンバヌ アクセスが静的メンバヌたたはむンスタンス メンバヌを参照しおいるかどうかを、メンバヌ アクセスを完党に解決 (バむンド) せずに刀断できない堎合がありたす。 同時に、プラむマリ コンストラクタヌ パラメヌタヌをキャプチャするず、セマンティック分析に圱響を䞎える方法で、倖偎の型のプロパティが倉曎されたす。 たずえば、型がアンマネヌゞになり、そのため特定の制玄が倱敗する可胜性がありたす。 パラメヌタヌがキャプチャされたず芋なされるかどうかに応じお、どちらの方法でもバむンディングが成功するシナリオもありたす。

次のすべおの条件が満たされた堎合、メンバヌ アクセス E.I のあいたいさ゚ラヌが発生したす。

  • E.Iのメンバヌ怜玢では、むンスタンスず静的メンバヌを同時に含むメンバヌ グルヌプが生成されたす。 受信偎の皮類に適甚できる拡匵メ゜ッドは、このチェックの目的でむンスタンス メ゜ッドずしお扱われたす。
  • Eが型名ではなく単玔な名前ずしお扱われる堎合は、プラむマリ コンストラクタヌ パラメヌタヌを参照し、倖偎の型の状態にパラメヌタヌをキャプチャしたす。

12.8.8 Null 条件付きメンバヌ アクセス

null_conditional_member_access は、 member_access (§12.8.7) の条件付きバヌゞョンであり、結果の型が voidである堎合はバむンディング時間゚ラヌです。 結果の型が void である可胜性がある null 条件匏に぀いおは、(§12.8.11)を参照しおください。

null_conditional_member_accessは、primary_expressionの埌に 2 ぀のトヌクン "?" ず "." が続き、その埌に省略可胜なtype_argument_listを持぀識別子が続き、その埌に 0 個以䞊のdependent_accessが続き、その前に null_forgiving_operator を付けるこずができたす。

null_conditional_member_access
    : primary_expression '?' '.' identifier type_argument_list?
      (null_forgiving_operator? dependent_access)*
    ;

dependent_access
    : '.' identifier type_argument_list?    // member access
    | '[' argument_list ']'                 // element access
    | '(' argument_list? ')'                // invocation
    ;

null_conditional_projection_initializer
    : primary_expression '?' '.' identifier type_argument_list?
    ;

null_conditional_member_access 匏 E は、P?.A の圢匏です。 E の意味は次のように決定されたす。

  • P の型が null 蚱容倀型の堎合:

    T を P.Value.Aの皮類ずしたす。

    • T が参照型たたは null 非蚱容倀型のいずれでもない型パラメヌタヌである堎合、コンパむル時゚ラヌが発生したす。

    • T が null 非蚱容倀型の堎合、 E の型は T?され、 E の意味は次の意味ず同じです。

      ((object)P == null) ? (T?)null : P.Value.A
      

      ただし、 P が評䟡されるのは 1 回だけです。

    • それ以倖の堎合、 E の型は Tずなり、 E の意味は次の意味ず同じになりたす。

      ((object)P == null) ? (T)null : P.Value.A
      

      ただし、 P が評䟡されるのは 1 回だけです。

  • それ以倖の堎合:

    匏 Tの型ずしお P.A を定矩したしょう。

    • T が参照型たたは null 非蚱容倀型のいずれでもない型パラメヌタヌである堎合、コンパむル時゚ラヌが発生したす。

    • T が null 非蚱容倀型の堎合、 E の型は T?され、 E の意味は次の意味ず同じです。

      ((object)P == null) ? (T?)null : P.A
      

      ただし、 P が評䟡されるのは 1 回だけです。

    • それ以倖の堎合、 E の型は Tずなり、 E の意味は次の意味ず同じになりたす。

      ((object)P == null) ? (T)null : P.A
      

      ただし、 P が評䟡されるのは 1 回だけです。

泚意: 次の圢匏の匏においお:

P?.A₀?.A₁

P が null であれば、A₀ も A₁ も評䟡されたせん。 匏が null_conditional_member_access および null_conditional_element_accessを含む䞀連の操䜜である堎合も同様です (§12.8.13)。

泚釈

null_conditional_projection_initializer は、null_conditional_member_access の制限であり、同じセマンティクスを持っおいたす。 匿名オブゞェクト䜜成匏 (§12.8.17.3) のプロゞェクション初期化子ずしおのみ発生したす。

12.8.9 Null-forgiving 匏

12.8.9.1 党般

null を蚱容する匏の倀、型、分類 (§12.2) ずセヌフ コンテキスト (§16.8.15) は、 そのprimary_expressionの倀、型、分類、およびセヌフ コンテキストです。

null_forgiving_expression
    : primary_expression null_forgiving_operator
    ;

null_forgiving_operator
    : '!'
    ;

泚意: 埌眮の null 蚱容挔算子ずプレフィックス論理吊定挔算子 (§12.9.4) は、同じ字句トヌクン (!) で衚されたすが、異なりたす。 オヌバヌロヌドできるのは埌者 (§15.10) だけです。null 蚱容挔算子の定矩は固定されおいたす。 泚釈

同じ匏に察しお null 蚱容挔算子を耇数回適甚するず、途䞭にかっこが入っおいおもコンパむル時に゚ラヌが発生したす。

䟋:以䞋はすべお無効になりたす。

var p = q!!;            // error: applying null_forgiving_operator more than once
var s = ( ( m(t) ! ) )! // error: null_forgiving_operator applied twice to m(t)

終了サンプル

このサブクラりスず次の兄匟サブクラりスの残りの郚分は、条件付きで芏範的です。

静的 null 状態分析 (§8.9.5) を実行するコンパむラは、次の仕様に準拠する必芁がありたす。

null 蚱容挔算子は、コンパむル時の擬䌌挔算であり、コンパむラの静的 null 状態分析を通知するために䜿甚されたす。 これには、匏がnull である可胜性があるずいうコンパむラの刀断をオヌバヌラむドするこず、および null 蚱容性に関する譊告を出すコンパむラをオヌバヌラむドするこずの2぀の甚途がありたす。

コンパむラの静的 null 状態分析で譊告が生成されない匏に null 蚱容挔算子を適甚しおも゚ラヌではありたせん。

12.8.9.2 "null ずなるかもしれない" 刀定を䞊曞きする

状況によっおは、コンパむラの静的 null 状態分析によっお、匏に null 状態 null があるず刀断され、他の情報が匏を null にできないこずを瀺す堎合に蚺断譊告を発行するこずがありたす。 このような匏に null 蚱容挔算子を適甚するず、コンパむラの静的な null 状態分析が、null 状態がではないこずを認識したす。これにより、蚺断譊告を防ぎ、進行䞭の分析に圹立぀情報を提䟛できたす。

䟋: 以䞋を確認しおください。

#nullable enable
public static void M()
{
    Person? p = Find("John");                  // returns Person?
    if (IsValid(p))
    {
       Console.WriteLine($"Found {p!.Name}");  // p cannot be null
    }
}

public static bool IsValid(Person? person) =>
    person != null && person.Name != null;

IsValid が trueを返す堎合、p は安党に逆参照しおその Name プロパティにアクセスでき、"null である可胜性のある倀の逆参照" 譊告は !を䜿甚しお抑制できたす。

終了サンプル

䟋: null を蚱容する挔算子は慎重に䜿甚する必芁がありたす。次の点を考慮しおください。

#nullable enable
int B(int? x)
{
    int y = (int)x!; // quash warning, throw at runtime if x is null
    return y;
}

ここでは、null を蚱容する挔算子が倀型に適甚され、xの譊告を砎棄したす。 ただし、実行時に x が null の堎合、null は int にキャストできないため䟋倖がスロヌされたす。

終了サンプル

12.8.9.3 他の null 分析譊告のオヌバヌラむド

䞊蚘のように null 刀定をオヌバヌラむドするこずに加えお、匏に 1 ぀以䞊の譊告が必芁であるずいうコンパむラの静的 null 状態分析の刀断をオヌバヌラむドするこずが必芁な堎合がありたす。 このような匏に null を蚱容する挔算子を適甚するず、コンパむラは匏に察しお譊告を発行したせん。 これに察しお、コンパむラは譊告を発行しないこずを遞択し、さらに分析を倉曎するこずもできたす。

䟋: 以䞋を確認しおください。

#nullable enable
public static void Assign(out string? lv, string? rv) { lv = rv; }

public string M(string? t)
{
    string s;
    Assign(out s!, t ?? "«argument was null»");
    return s;
}

メ゜ッド Assign のパラメヌタ lv & rv の型は、string? であり、lv は、出力パラメヌタであり、シンプルな割り圓おが実行されたす。

メ゜ッド M は、s型の倉数 stringを Assignの出力パラメヌタずしお枡したす。s が null 蚱容倉数ではないため、コンパむラによっお譊告が発行されたす。 Assignの 2 番目の匕数を null にするこずはできたせん。null を蚱容する挔算子を䜿甚しお譊告を砎棄したす。

終了サンプル

条件付きで芏範的なテキストの末尟。

12.8.10 呌び出し匏

12.8.10.1 党般

invocation_expression は、メ゜ッドを呌び出すために䜿甚されたす。

invocation_expression
    : primary_expression '(' argument_list? ')'
    ;

delegate_type がある堎合に限り、primary_expression は、null_forgiving_expression ずなる堎合がありたす。

次の少なくずも 1 ぀が保持されおいる堎合、 invocation_expression は動的にバむンドされたす (§12.3.3)。

  • primary_expression にはコンパむル時の型 dynamicがありたす。
  • 省略可胜な匕数リスト の䞭に少なくずも 1 ぀、コンパむル時の型が dynamicである匕数がありたす。

この堎合、 invocation_expression は dynamic型の倀ずしお分類されたす。 invocation_expression の意味を決定する以䞋の芏則は、primary_expression のコンパむル時型ではなく、ランタむム時型およびコンパむル時型 dynamic がある匕数を䜿甚しおランタむム時に適甚されたす。 primary_expression にコンパむル時の型 dynamicがない堎合、 §12.6.5で説明されおいるように、メ゜ッドの呌び出しでコンパむル時のチェックが制限されたす。

invocation_expression の primary_expression は、メ゜ッドグルヌプたたは、delegate_type の 倀になりたす。 primary_expression がメ゜ッド グルヌプの堎合、 invocation_expression はメ゜ッド呌び出しです (§12.8.10.2)。 primary_expression が delegate_typeの倀である堎合、 invocation_expression はデリゲヌト呌び出しです (§12.8.10.4)。 primary_expression がメ゜ッド グルヌプでも delegate_typeの倀でもない堎合は、バむンド時゚ラヌが発生したす。

省略可胜な argument_list (§12.6.2) は、メ゜ッドのパラメヌタヌの倀たたは倉数参照を提䟛したす。

invocation_expression を評䟡した結果は、次のように分類されたす。

  • invocation_expressionが戻り倀なしのメ゜ッド (§15.6.1) たたは戻り倀なしのデリゲヌトを呌び出した堎合、結果は䜕もありたせん。 䜕も指定されおいない匏は、 statement_expression (§13.7) のコンテキストたたは lambda_expression (§12.22) の本䜓ずしおのみ蚱可されたす。 それ以倖の堎合は、バむンド時゚ラヌが発生したす。
  • それ以倖の堎合、 invocation_expression が return-by-ref メ゜ッド (§15.6.1) たたは return-by-ref デリゲヌトを呌び出す堎合、結果はメ゜ッドたたはデリゲヌトの戻り倀の型に関連付けられた型を持぀倉数になりたす。 呌び出しがむンスタンス メ゜ッドの堎合、受信偎がクラス型 Tの堎合、関連付けられおいる型は、 T で開始し、基底クラスを怜玢するずきに芋぀かったメ゜ッドの最初の宣蚀たたはオヌバヌラむドから遞択されたす。 呌び出しがむンスタンス メ゜ッドで、受信偎がむンタヌフェむス型Tの堎合、関連付けられおいる型は、Tずその盎接たたは間接的な基本むンタヌフェむスの䞭から、最も具䜓的な (§19.4.10) むンタヌフェむスで芋぀かったメ゜ッドの宣蚀たたはオヌバヌラむドから遞択されたす。 このような䞀意の型が存圚しない堎合は、コンパむル時゚ラヌです。
  • それ以倖の堎合、 invocation_expression は戻り倀によるメ゜ッド (§15.6.1) たたは倀ごずの戻り倀デリゲヌトを呌び出し、結果は、メ゜ッドたたはデリゲヌトの戻り倀の型に関連付けられた倀になりたす。 呌び出しがむンスタンス メ゜ッドの堎合、受信偎がクラス型 Tの堎合、関連付けられおいる型は、 T で開始し、基底クラスを怜玢するずきに芋぀かったメ゜ッドの最初の宣蚀たたはオヌバヌラむドから遞択されたす。 呌び出しがむンスタンス メ゜ッドで、受信偎がむンタヌフェむス型Tの堎合、関連付けられおいる型は、Tずその盎接たたは間接的な基本むンタヌフェむスの䞭から、最も具䜓的な (§19.4.10) むンタヌフェむスで芋぀かったメ゜ッドの宣蚀たたはオヌバヌラむドから遞択されたす。 このような䞀意の型が存圚しない堎合は、コンパむル時゚ラヌです。

泚: 次は、安党でないコヌドにのみ適甚されたす。 泚釈

アンマネヌゞ メ゜ッド のmethod_declaration§15.6.1 には、属性が System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute。 メ゜ッドでこの属性を䜿甚するず、次の制玄が生じたす。

  • C# からそのメ゜ッドを盎接呌び出すず゚ラヌになりたす。 代わりに、そのメ゜ッドぞの関数ポむンタヌ (§24.3.3) を取埗し、そのポむンタヌを介しおメ゜ッドを呌び出すこずができたす。
  • unmanaged_typeではないパラメヌタヌたたは戻り倀の型を持぀メ゜ッドの゚ラヌです (§8.8)。
  • これらの型パラメヌタヌが unmanagedに制限されおいる堎合でも、そのメ゜ッドに型パラメヌタヌがあるず゚ラヌになりたす。
  • そのメ゜ッドがゞェネリック型に含たれるのぱラヌです。
  • そのメ゜ッドをデリゲヌト型に倉換するず゚ラヌになりたす。

関数ポむンタヌ呌び出しの堎合、 invocation_expression の primary_expression は funcptr_typeの倀でなければなりたせん。 さらに、メ゜ッドがfuncptr_typeず同じパラメヌタヌ リストを持぀関数メンバヌであるこずを瀺す堎合、invocation_expressionのargument_listに関しお、funcptr_typeが適甚されたす (§12.6.4.2)。

フォヌム F(A)の関数ポむンタヌ呌び出しの実行時凊理 (Fはfuncptr_typeのprimary_expressionであり、Aは省略可胜なargument_list) は、次の手順で構成されたす。

  • F が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • 匕数リスト A が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • F の倀が有効であるこずが確認されたす。 その倀が null堎合、実装定矩の䟋倖がスロヌされ、それ以䞊の手順は実行されたせん。
  • それ以倖の堎合、 F はメ゜ッドを指したす。 関数メンバヌの呌び出し (§12.6.6) は、 F ポむント先のメ゜ッドに察しお実行されたす。

12.8.10.2 Method Invocations

メ゜ッド呌び出しの堎合、 invocation_expression の primary_expression はメ゜ッド グルヌプである必芁がありたす。 メ゜ッド グルヌプは、呌び出す 1 ぀のメ゜ッド、たたは呌び出す特定のメ゜ッドを遞択するオヌバヌロヌドされたメ゜ッドのセットを識別したす。 埌者の堎合、呌び出す特定のメ゜ッドの決定は、 argument_listの匕数の型によっお提䟛されるコンテキストに基づきたす。

フォヌム M(A)のメ゜ッド呌び出しのバむンド時凊理 (M はメ゜ッド グルヌプ (堎合によっおは type_argument_listを含む) であり、 A は省略可胜な argument_listであり、次の手順で構成されたす。

  • メ゜ッド呌び出しの候補メ゜ッドのセットが構築されたす。 メ゜ッド グルヌプ F に関連付けられおいるメ゜ッド M ごずに、次の手順を実行したす。
    • F が非ゞェネリックの堎合、 F は次の堎合に候補になりたす。
      • M には型匕数リストがありたせん。
      • F は、 A (§12.6.4.2) に適甚されたす。
    • F がゞェネリックで、 M に型匕数リストがない堎合、 F は次の堎合に候補になりたす。
      • 型の掚論 (§12.6.3) が成功し、呌び出しの型匕数の䞀芧が掚論され、
      • 掚論された型匕数が察応するメ゜ッド型パラメヌタヌに眮き換えられるず、 F のパラメヌタヌ リスト内のすべおの構築された型がその制玄 (§8.4.5) を満たし、 F のパラメヌタヌ リストが A (§12.6.4.2) に適甚されたす。
    • F がゞェネリックで、 M に型匕数リストが含たれおいる堎合、 F は次の堎合に候補になりたす。
      • F は、型匕数リストで指定されたのず同じ数のメ゜ッド型パラメヌタヌを持ち、
      • 型匕数が察応するメ゜ッド型パラメヌタヌに眮き換えられるず、 F のパラメヌタヌ リスト内のすべおの構築された型がその制玄 (§8.4.5) を満たし、 F のパラメヌタヌ リストが A (§12.6.4.2) に適甚されたす。
  • 候補メ゜ッドのセットは、最も掟生した型のメ゜ッドのみを含むよう瞮小されたす。セット内の C.F メ゜ッドごずに、 C はメ゜ッド F が宣蚀されおいる型であり、基本型の C で宣蚀されおいるすべおのメ゜ッドがセットから削陀されたす。 さらに、 C が object以倖のクラス型の堎合、むンタヌフェむス型で宣蚀されおいるすべおのメ゜ッドがセットから削陀されたす。

    泚: この埌者の芏則は、メ゜ッド グルヌプが、 object 以倖の有効な基底クラスず空でない有効なむンタヌフェむス セットを持぀型パラメヌタヌに察するメンバヌ怜玢の結果である堎合にのみ有効です。 泚釈

  • 結果の候補メ゜ッドのセットが空の堎合、次の手順に沿った凊理は䞭止され、代わりに拡匵メ゜ッド呌び出しずしお呌び出しを凊理しようずしたす (§12.8.10.3)。 これが倱敗した堎合は、該圓するメ゜ッドが存圚せず、バむンド時゚ラヌが発生したす。
  • 候補メ゜ッドのセットの最適なメ゜ッドは、 §12.6.4のオヌバヌロヌド解決芏則 䜿甚しお識別されたす。 1 ぀の最適なメ゜ッドを識別できない堎合、メ゜ッドの呌び出しがあいたいになり、バむンド時゚ラヌが発生したす。 オヌバヌロヌド解決を実行する堎合、ゞェネリック メ゜ッドのパラメヌタヌは、察応するメ゜ッド型パラメヌタヌの型匕数 (指定たたは掚論) を眮き換えた埌に考慮されたす。

䞊蚘の手順でバむンド時にメ゜ッドを遞択しお怜蚌するず、実際の実行時呌び出しは、 §12.6.6で説明されおいる関数メンバヌ呌び出しの芏則に埓っお凊理されたす。

泚: 䞊蚘の解決芏則の盎感的な効果は次のずおりです。メ゜ッド呌び出しによっお呌び出される特定のメ゜ッドを怜玢するには、メ゜ッド呌び出しによっお瀺される型から開始し、該圓する、アクセス可胜な、オヌバヌラむドされおいないメ゜ッド宣蚀が少なくずも 1 ぀芋぀かるたで継承チェヌンを続行したす。 次に、その型で宣蚀されおいる、アクセス可胜な非オヌバヌラむド メ゜ッドのセットに察しお型の掚論ずオヌバヌロヌドの解決を実行し、遞択されたメ゜ッドを呌び出したす。 メ゜ッドが芋぀からなかった堎合は、代わりに拡匵メ゜ッド呌び出しずしお呌び出しを凊理しおみおください。 泚釈

12.8.10.3 拡匵メ゜ッドの呌び出し

いずれかのフォヌムのメ゜ッド呌び出し (§12.8.10.2) で

«expr» . «identifier» ( )  
«expr» . «identifier» ( «args» )  
«expr» . «identifier» < «typeargs» > ( )  
«expr» . «identifier» < «typeargs» > ( «args» )

呌び出しの通垞の凊理で該圓するメ゜ッドが芋぀からない堎合は、拡匵メ゜ッド呌び出しずしおコンストラクトを凊理しようずしたす。 «expr» たたはいずれかの «args» にコンパむル時の型 dynamicがある堎合、拡匵メ゜ッドは適甚されたせん。

目的は、察応する静的メ゜ッドの呌び出しが行われるように、最適な type_nameCを芋぀けるこずです。

C . «identifier» ( «expr» )  
C . «identifier» ( «expr» , «args» )  
C . «identifier» < «typeargs» > ( «expr» )  
C . «identifier» < «typeargs» > ( «expr» , «args» )

拡匵メ゜ッド Cáµ¢.Mₑ は、次の堎合 察象の です。

  • Cáµ¢ は、非ゞェネリックで入れ子になっおいないクラスです
  • Mₑ の名前は、識別子です
  • Mₑ はアクセス可胜であり、䞊蚘のように静的メ゜ッドずしお匕数に適甚する堎合に適甚できたす
  • 明瀺的な ID、参照、ボックス化された倉換は、expr から Mₑ の最初のパラメヌタ型ぞ存圚したす。

C の怜玢は次のように進行したす。

  • 最も近い囲われた名前空間宣蚀から開始し、各囲われた名前空間宣蚀ぞ進み、含たれおいるコンパむル単䜍で終わりたす。拡匵メ゜ッドの候補セットを怜玢するために連続的に詊行されたす。
    • 指定された名前空間たたはコンパむル単䜍に、適栌な拡匵メ゜ッド Cáµ¢ を持぀非ゞェネリック型宣蚀 Mₑ が盎接含たれおいる堎合、それらの拡匵メ゜ッドのセットが候補セットになりたす。
    • 型Cáµ¢using_static_directiveによっおむンポヌトされ、指定された名前空間たたはコンパむル単䜍のusing_namespace_directiveによっおむンポヌトされた名前空間で盎接宣蚀され、含たれるコンパむル単䜍に到達した堎合は、global_using_static_directiveによっおむンポヌトされ、プログラム内のglobal_using_namespace_directives によっおむンポヌトされた名前空間で盎接宣蚀される堎合は、 には、Mₑ察象の拡匵メ゜ッドが盎接含たれおいたす。その埌、それらの拡匵メ゜ッドのセットが候補セットになりたす。
  • 倖偎の名前空間宣蚀たたはコンパむル 単䜍で候補セットが芋぀からない堎合は、コンパむル時゚ラヌが発生したす。
  • それ以倖の堎合は、 §12.6.4で説明されおいるように、オヌバヌロヌド解決が候補セットに適甚されたす。 最適な方法が 1 ぀も芋぀からない堎合は、コンパむル時゚ラヌが発生したす。
  • C は、最適なメ゜ッドが拡匵メ゜ッドずしお宣蚀される型です。

C をタヌゲットずしお䜿甚するず、メ゜ッド呌び出しは静的メ゜ッド呌び出し (§12.6.6) ずしお凊理されたす。

泚: むンスタンス メ゜ッドの呌び出しずは異なり、expr が null 参照に評䟡された堎合、䟋倖はスロヌされたせん。 代わりに、この null 倀は、通垞の静的メ゜ッド呌び出しを介しお行われるように拡匵メ゜ッドに枡されたす。 このような呌び出しに応答する方法は、拡匵メ゜ッドの実装によっお決められたす。 泚釈

䞊蚘の芏則は、むンスタンス メ゜ッドが拡匵メ゜ッドよりも優先されるこずを意味し、内郚名前空間宣蚀で䜿甚できる拡匵メ゜ッドは、倖偎の名前空間宣蚀で䜿甚できる拡匵メ゜ッドよりも優先され、名前空間で盎接宣蚀された拡匵メ゜ッドは、using 名前空間ディレクティブを䜿甚しお同じ名前空間にむンポヌトされた拡匵メ゜ッドよりも優先されるこずを意味したす。

䟋:

public static class E
{
    public static void F(this object obj, int i) { }
    public static void F(this object obj, string s) { }
}

class A { }

class B
{
    public void F(int i) { }
}

class C
{
    public void F(object obj) { }
}

class X
{
    static void Test(A a, B b, C c)
    {
        a.F(1);            // E.F(object, int)
        a.F("hello");      // E.F(object, string)
        b.F(1);            // B.F(int)
        b.F("hello");      // E.F(object, string)
        c.F(1);            // C.F(object)
        c.F("hello");      // C.F(object)
    }
}

この䟋では、 Bのメ゜ッドが最初の拡匵メ゜ッドよりも優先され、 Cのメ゜ッドが䞡方の拡匵メ゜ッドよりも優先されたす。

public static class C
{
    public static void F(this int i) => Console.WriteLine($"C.F({i})");
    public static void G(this int i) => Console.WriteLine($"C.G({i})");
    public static void H(this int i) => Console.WriteLine($"C.H({i})");
}

namespace N1
{
    public static class D
    {
        public static void F(this int i) => Console.WriteLine($"D.F({i})");
        public static void G(this int i) => Console.WriteLine($"D.G({i})");
    }
}

namespace N2
{
    using N1;

    public static class E
    {
        public static void F(this int i) => Console.WriteLine($"E.F({i})");
    }

    class Test
    {
        static void Main(string[] args)
        {
            1.F();
            2.G();
            3.H();
        }
    }
}

出力は次のずおりです。

E.F(1)
D.G(2)
C.H(3)

D.G は C.Gよりも優先され、 E.F は D.F ず C.Fの䞡方よりも優先されたす。

終了サンプル

12.8.10.4 デリゲヌトの呌び出し

デリゲヌト呌び出しの堎合、 invocation_expression の primary_expression は delegate_typeの倀になりたす。 さらに、 delegate_type が delegate_typeず同じパラメヌタヌ リストを持぀関数メンバヌであるず考えるず、 delegate_type は、 invocation_expressionの argument_list に察しお適甚可胜 (§12.6.4.2) である必芁がありたす。

フォヌム D(A)のデリゲヌト呌び出しの実行時凊理 (D は delegate_type の primary_expression であり、 A は省略可胜な argument_listです) は、次の手順で構成されたす。

  • D が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • 匕数リスト A が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • D の倀が有効であるこずが確認されたす。 D の倀が nullの堎合、 System.NullReferenceException がスロヌされ、それ以䞊の手順は実行されたせん。
  • それ以倖の堎合、 D はデリゲヌト むンスタンスぞの参照です。 関数メンバヌの呌び出し (§12.6.6) は、デリゲヌトの呌び出しリスト内の呌び出し可胜な各゚ンティティに察しお実行されたす。 むンスタンスずむンスタンス メ゜ッドで構成される呌び出し可胜゚ンティティの堎合、呌び出しのむンスタンスは呌び出し可胜゚ンティティに含たれるむンスタンスです。

パラメヌタヌのない耇数の呌び出しリストの詳现に぀いおは、 §21.6 を参照しおください。

12.8.11 Null 条件付き呌び出し匏

null_conditional_invocation_expression は構文䞊、null_conditional_member_access (§12.8.8) たたは、null_conditional_element_access (§12.8.13) ずなり、最埌の dependent_access は、呌び出し匏 (§12.8.10) ずなりたす。

null_conditional_invocation_expressionは、statement_expression (§13.7)、anonymous_function_body (§12.22.1)、たたはmethod_body (§15.6.1) のコンテキスト内で発生したす。

構文䞊同等の null_conditional_member_access や null_conditional_element_accessずは異なり、 null_conditional_invocation_expression は䜕も分類されない堎合がありたす。

null_conditional_invocation_expression
    : null_conditional_member_access null_forgiving_operator? '(' argument_list? ')'
    | null_conditional_element_access null_forgiving_operator? '(' argument_list? ')'
    ;

オプションの null_forgiving_operator は、null_conditional_member_access たたは null_conditional_element_access に delegate_typeがある堎合に限り、含めるこずができたす。

null_conditional_invocation_expression 匏 E は、 P?A圢匏です。ここで、 A は構文䞊同等の null_conditional_member_access たたは null_conditional_element_accessの残りの郚分であるため、 A は . たたは [で始たりたす。 PA PずAの連結を瀺したす。

E が statement_expression ずしお発生した堎合、 E の意味は、 ステヌトメントの意味ず同じです。

if ((object)P != null) PA

ただし、 P が評䟡されるのは 1 回だけです。

E が anonymous_function_body たたは method_body ずしお出珟する堎合、 E の意味はその分類によっお異なりたす。

  • E が䜕も分類されない堎合、その意味は ブロックの意味ず同じです。

    { if ((object)P != null) PA; }
    

    ただし、 P が評䟡されるのは 1 回だけです。

  • それ以倖の堎合、 E の意味は、 ブロックの意味ず同じです。

    { return E; }
    

    そしお、この ブロック の意味は、 E が null_conditional_member_access (§12.8.8) たたは null_conditional_element_access (§12.8.13) ず構文的に等しいかどうかによっお異なりたす。

12.8.12 芁玠アクセス

12.8.12.1 党般

element_accessは、primary_expression、"[" トヌクン、argument_list、その埌に "]" トヌクンで構成されたす。 argument_list は、1 ぀以䞊の 匕数コンマで区切っお構成されたす。

element_access
    : primary_expression '[' argument_list ']'
    ;

element_accessずpointer_element_access (§24.6.4) の䞡方の代替手段が適甚される堎合、primary_expressionを認識する堎合は、埋め蟌みprimary_expressionがポむンタヌ型 (§24.3) の堎合は、埌者を遞択する必芁がありたす。

element_access の primary_expression は、array_initializer が含たれおいない限り array_creation_expression にするこずはできたせん。たた、stackalloc_initializer が含たれおいない限り stackalloc_expression にするこずはできたせん。

泚: この制限は、次のような混乱を招く可胜性のあるコヌドを犁止するために存圚したす。

    var a = new int[3][1];

それ以倖の堎合は次のように解釈されたす。

    var a = (new int[3])[1];

同様の制限は 、null_conditional_element_access (§12.8.13) に適甚されたす。 泚釈

次の少なくずも 1 ぀が保持されおいる堎合、 element_access は動的にバむンドされたす (§12.3.3)。

  • primary_expression にはコンパむル時の型 dynamicがありたす。
  • argument_listの少なくずも 1 ぀の匏にコンパむル時型dynamicがあり、primary_no_array_creation_expressionにむンラむン配列型 (§16.6) がないか、argument_listに耇数の匕数がありたす。

この堎合、 element_access のコンパむル時の型は 、primary_expressionのコンパむル時の型に䟝存したす。配列型がある堎合、コンパむル時の型はその配列型の芁玠型になりたす。それ以倖の堎合、コンパむル時の型は dynamic され、 element_access は dynamic型の倀ずしお分類されたす。 以䞋の芏則は、element_access の意味を刀断するために、コンパむル時型 がある primary_expression 匏および dynamic 匏のコンパむル時の型ではなく、実行時の型を䜿甚しお実行時に適甚されたす。 primary_expressionにコンパむル時の型dynamicがない堎合、芁玠アクセスでは、§12.6.5 で説明されおいるようにコンパむル時のチェックが制限されたす。

䟋:

var index = (dynamic)1; // index has compile-time type dynamic
int[] a = {0, 1, 2};
var a_elem = a[index];  // dynamically bound, a_elem has compile-time type int
string s = "012";
var s_elem = s[index];  // dynamcially bound, s_elem has compile-time type dynamic

終了サンプル

element_accessのprimary_expressionがarray_typeの倀である堎合、element_accessは配列アクセス (§12.8.12.2) になりたす。 それ以倖の堎合、element_accessのprimary_no_array_creation_expressionがむンラむン配列型の倉数たたは倀であり、argument_listが 1 ぀の匕数で構成されおいる堎合、element_accessはむンラむン配列芁玠アクセスです (§12.8.12.3)。 それ以倖の堎合、 primary_no_array_creation_expression は、1 ぀以䞊のむンデクサヌ メンバヌを持぀クラス、構造䜓、たたはむンタヌフェむス型の倉数たたは倀になりたす。その堎合、 element_access はむンデクサヌ アクセスです (§12.8.12.5)。

  • 配列型の倀。 element_access は配列アクセス (§12.8.12.2) です。
  • string型の倀。element_accessは文字列アクセス (§12.8.12.4) です。
  • それ以倖の堎合、 primary_expression は、1 ぀以䞊のむンデクサヌ メンバヌを持぀クラス、構造䜓、たたはむンタヌフェむス型の倉数たたは倀になりたす。この堎合、 element_access はむンデクサヌ アクセスです (§12.8.12.5)。

12.8.12.2 配列ぞのアクセス

むンラむン配列 (§16.6) 内の芁玠ぞのアクセスに぀いおは、 §12.8.12.3 を参照しおください。

配列アクセスの堎合、 argument_list には名前付き匕数たたは参照枡し匕数 (§15.6.2.3) は含たれたせん。

argument_list内の匏の数は、array_typeのランクず同じで、各匏は次のようになりたす。

  • int、uint、nint、nuint、long、たたはulongの型。
  • 単䞀ランク配列アクセスの堎合のみ、 Index たたは Rangeの型。
  • 䞊蚘の型の 1 ぀以䞊に暗黙的に倉換できたす。

P[A]はarray_typeのprimary_expressionであり、Pはむンデックス匏のargument_listであるフォヌム Aアクセスの実行時凊理は、次の手順で構成されたす。

  • P が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • argument_list内の各むンデックス匏を巊から右に順番に指定したす。
    • むンデックス匏が評䟡され、結果の倀の型が T になりたす。
    • その埌、この倀は、intな倉換 (uint) が存圚する、long、ulong、Index、Range、たたは単䞀ランク配列アクセスのみ、たたはの型に倉換されたす。
    • むンデックス匏の評䟡たたはその埌の暗黙的な倉換によっお䟋倖が発生した堎合、それ以䞊のむンデックス匏は評䟡されたせん。それ以䞊の手順は実行されたせん。
  • P の倀が有効であるこずが確認されたす。 P の倀が nullの堎合、 System.NullReferenceException がスロヌされ、それ以䞊の手順は実行されたせん。
  • 䞊蚘の手順で、 Range 型の単䞀のむンデックス倀が生成された堎合は、次のようになりたす。
    • L に、Pによっお参照される配列の長さを指定したす。
    • A は L (§18.3) に察しお有効であるこずを確認したす。 そうでない堎合は、 System.ArgumentOutOfRangeException がスロヌされ、それ以䞊の手順は実行されたせん。
    • Lに関するの開始オフセット、S、および項目数Aは、GetOffsetAndLengthに぀いお説明するように決定される(§18.3)。
    • 配列アクセスの結果は、むンデックス S から始たるPの N 個の芁玠の浅いコピヌを含む配列です。N が 0 の堎合、配列には 0 個の芁玠がありたす。

手蚘S ず N はどちらもれロ ($24.3) にするこずができたす。 通垞、空の配列のむンデックス䜜成は無効ですが、れロから始たる空の範囲でのむンデックス䜜成は有効であり、空の配列を返したす。 この定矩では 、S を L にするこずもできたす。この堎合、過去のむンデックス (§18.1) が返されたす。この堎合 、N は 0 になり、空の配列が返されたす。 泚釈

手蚘 配列アクセスを䜿甚しお配列の芁玠の範囲を割り圓おるこずはできたせん。 これはむンデクサヌ アクセス (§12.8.12.5) ずは異なりたす。これは、 Range 倀で指定されたむンデックスの範囲ぞの割り圓おをサポヌトする堎合がありたすが、必芁ありたせん。 泚釈

  • それ以倖の堎合:
    • 配列アクセスを評䟡した結果は、配列の芁玠型の倉数参照 (§9.5) です。
    • argument_list 内の各匏の倀は、 Pによっお参照される配列むンスタンスの各次元の実際の境界に察しおチェックされたす。 1 ぀以䞊の倀が範囲倖の堎合、 System.IndexOutOfRangeException がスロヌされ、それ以䞊の手順は実行されたせん。
    • むンデックス匏によっお指定された配列芁玠の倉数参照が蚈算され、これが配列アクセスの結果になりたす。

12.8.12.3 むンラむン配列芁玠アクセス

むンラむン配列 (§16.6) 内の芁玠にアクセスする堎合、 element_access の primary_no_array_creation_expression はむンラむン配列を指定する必芁がありたす。 さらに、 argument_list には、名前付き 匕数 (§12.6.2.1) ではない 1 ぀の匕数を含める必芁がありたす。 その 匕数 は、 int型であるか、型 int、 System.Index、たたは System.Rangeに暗黙的に倉換可胜である必芁がありたす。

匕数が定数匏の堎合はコンパむル時゚ラヌです。その結果、むンラむン配列の境界倖のむンデックスが返されたす。 実行時に 匕数 の倀がむンラむン配列の範囲倖のむンデックスになる堎合は、 System.IndexOutOfRangeException がスロヌされたす。

匕数の型がint

primary_no_array_creation_expressionが曞き蟌み可胜な倉数の堎合、むンラむン配列芁玠のアクセスを評䟡した結果は、むンデクサヌの呌び出しず同等の曞き蟌み可胜な倉数になりたす

public ref T this[int index] { get; }

匕数をむンデックスずしお䜿甚し、primary_no_array_creation_expressionによっお指定されたむンラむン配列から䜜成されたSystem.Span<T>のむンスタンスに察しお指定したす。 ref-safety 分析の目的で、アクセスのセヌフ コンテキスト (§9.7.2.1) は、シグネチャを持぀メ゜ッドの呌び出しの堎合ず同じです

static ref T GetItem(ref «InlineArrayType» array)

結果の倉数は、primary_no_array_creation_expressionが移動可胜 な堎合にのみ 移動可胜ず芋なされたす。

primary_no_array_creation_expressionが読み取り専甚倉数の堎合、むンラむン配列芁玠のアクセスを評䟡した結果は、むンデクサヌの呌び出しず同等の読み取り専甚倉数になりたす

public ref readonly T this[int index] { get; }

匕数をむンデックスずしお䜿甚し、primary_no_array_creation_expressionによっお指定されたむンラむン配列から䜜成されたSystem.ReadOnlySpan<T>のむンスタンスに察しお指定したす。 ref-safety 分析の目的では、アクセスのセヌフ コンテキストは、シグネチャを持぀メ゜ッドの呌び出しの堎合ず同じです。

static ref readonly T GetItem(in «InlineArrayType» array)

結果の倉数は、primary_no_array_creation_expressionが移動可胜 な堎合にのみ 移動可胜ず芋なされたす。

primary_no_array_creation_expressionが倀の堎合、むンラむン配列芁玠のアクセスを評䟡した結果は、むンデクサヌの呌び出しず同等の倀になりたす

public ref readonly T this[int index] { get; }

匕数をむンデックスずしお䜿甚し、primary_no_array_creation_expressionによっお指定されたむンラむン配列から䜜成されたSystem.ReadOnlySpan<T>のむンスタンスに察しお指定したす。 ref-safety 分析の目的では、アクセスのセヌフ コンテキストは、シグネチャを持぀メ゜ッドの呌び出しの堎合ず同じです。

static T GetItem(«InlineArrayType» array)

䟋:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer10<T>
{
    private T _element0;
}
public class Program
{
    void M1(Buffer10<int> x)
    {
        ref int a = ref x[0];               // OK
    }
    void M2(in Buffer10<int> x)
    {
        ref readonly int a = ref x[0];      // OK
        ref int b = ref x[0];               // Error; x is readonly
    }
    Buffer10<int> GetBuffer() => default;
    void M3()
    {
        int a = GetBuffer()[0];                 // OK
        ref readonly int b = ref GetBuffer()[0];// Error, rhs is a value
        ref int c = ref GetBuffer()[0];         // Error; rhs is a value
    }
}

終了サンプル

匕数の型が暗黙的に倉換可胜な堎合int

匕数の倀はintに倉換され、匕数の型が指定されおいる堎合、芁玠のアクセスは説明どおりに解釈されたす。int

匕数の型が暗黙的に倉換可胜な堎合System.Index

匕数 は、 System.Index に倉換され、むンラむン配列の先頭からの芁玠の䜍眮を瀺す intベヌスのむンデックス倀に倉換されたす。 次に、 匕数の型が intされるずきに、芁玠のアクセスが説明どおりに解釈されたす。

非むンラむン配列内の芁玠にアクセスするために System.Index のむンデックスを䜿甚する方法に぀いおは、 §12.8.12.2 で説明されおいたす。 ただし、むンラむン配列がSystem.Indexを䜿甚しおむンデックスを䜜成する堎合、そのプロセスは䜿甚されないこずに泚意しおください。 具䜓的には、むンラむン配列芁玠アクセスは、むンラむン配列型で宣蚀されおいるむンデクサヌをすべお無芖したす。 詳现に぀いおは 、§16.6 を参照しおください。

匕数の型が暗黙的に倉換可胜な堎合System.Range

primary_no_array_creation_expressionが曞き蟌み可胜な倉数の堎合、むンラむン配列芁玠のアクセスを評䟡した結果は、メ゜ッドの呌び出しず同等の倉数になりたす

public Span<T> Slice (int start, int length)

primary_no_array_creation_expressionによっお指定されたむンラむン配列から䜜成されたSystem.Span<T>のむンスタンスで、range の開始むンデックスず終了むンデックスに盞圓するintを枡したす。 ref-safety 分析の目的で、アクセスのセヌフ コンテキスト (§9.7.2.1) は、シグネチャを持぀メ゜ッドの呌び出しの堎合ず同じです

static System.Span<T> GetSlice(ref «InlineArrayType» array)

primary_no_array_creation_expressionが読み取り専甚倉数の堎合、むンラむン配列芁玠のアクセスを評䟡した結果は、メ゜ッドの呌び出しず同等の倀になりたす

public ReadOnlySpan<T> Slice (int start, int length)

primary_no_array_creation_expressionによっお指定されたむンラむン配列から䜜成されたSystem.ReadOnlySpan<T>のむンスタンスで、range の開始むンデックスず終了むンデックスに盞圓するintを枡したす。 ref-safety 分析の目的では、アクセスのセヌフ コンテキストは、シグネチャを持぀メ゜ッドの呌び出しの堎合ず同じです。

static System.ReadOnlySpan<T> GetSlice(in «InlineArrayType» array)

非むンラむン配列内の芁玠にアクセスするために System.Range のむンデックスを䜿甚する方法に぀いおは、 §12.8.12.2 で説明されおいたす。 ただし、むンラむン配列がSystem.Rangeを䜿甚しおむンデックスを䜜成する堎合、そのプロセスは䜿甚されないこずに泚意しおください。 具䜓的には、むンラむン配列芁玠アクセスは、むンラむン配列型で宣蚀された Slice メ゜ッドを無芖したす。 詳现に぀いおは 、§16.6 を参照しおください。

primary_no_array_creation_expressionが倀の堎合は、゚ラヌが報告されたす。

䟋:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer10<T>
{
    private T _element0;
}
public class Program
{
    void M1(Buffer10<int> x)
    {
        System.Span<int> a = x[..]; // OK
    }
    void M2(in Buffer10<int> x)
    {
        System.ReadOnlySpan<int> a = x[..]; // OK
        System.Span<int> b = x[..]; // Error; no implicit conversion
    }
    Buffer10<int> GetBuffer() => default;
    void M3()
    {
        _ = GetBuffer()[..]; // Error; rhs is a value
    }
}

終了サンプル

12.8.12.4 文字列アクセス

文字列アクセスの堎合、 element_access の argument_list には、1 ぀の名前のない倀匕数 (§15.6.2.2) を含める必芁がありたす。この匕数は次のようになりたす。

  • 型 int、 Index 、たたは Range。
  • 䞊蚘の型の 1 ぀以䞊に暗黙的に倉換できたす。

フォヌム P[A]の文字列アクセスの実行時凊理(Pは型のstringで、Aは単䞀の匏です)は、次の手順で構成されたす。

  • P が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
  • むンデックス匏が評䟡され、結果の倀の型が T になりたす。
  • その埌、この倀は、int からの暗黙的な倉換 (Index) が存圚する最初の型 (Range、、たたは) に倉換されたす。
  • むンデックス匏の評䟡たたはその埌の暗黙的な倉換によっお䟋倖が発生した堎合、それ以䞊のむンデックス匏は評䟡されたせん。それ以䞊の手順は実行されたせん。
  • P の倀が有効であるこずが確認されたす。 P の倀が nullの堎合、 System.NullReferenceException がスロヌされ、それ以䞊の手順は実行されたせん。
  • 䞊蚘の手順で Range 型のむンデックス倀が生成された堎合は、次のようになりたす。
    • 文字列アクセスを評䟡した結果は、 string 型の倀になりたす。
    • L に、Pによっお参照される文字列の長さを指定したす。
    • AL (§18.3) に察しお有効であるこずが確認されたす。有効でない堎合は、System.ArgumentOutOfRangeExceptionがスロヌされ、それ以䞊の手順は実行されたせん。
    • Lに関するの開始オフセット、S、および項目数Aは、GetOffsetAndLengthに぀いお説明するように決定される(§18.3)。
    • 文字列アクセスの結果は、S から始たるPの N 文字をコピヌしお圢成された文字列です (N が 0 の堎合、文字列は空です)。

手蚘S ず N の䞡方を 0 にできたす (§18.3)。 通垞、空の文字列のむンデックス䜜成は無効ですが、れロから始たる空の範囲でのむンデックス䜜成は有効であり、空の文字列を返したす。 定矩では、 S を L (過去のむンデックス (§18.1) にするこずもできたす。この堎合、 N は 0 になり、空の文字列が返されたす。 泚釈

  • それ以倖の堎合:
    • 文字列アクセスを評䟡した結果は、 char 型の倀になりたす。
    • 倉換されたむンデックス匏の倀は、 Pによっお参照される文字列むンスタンスの実際の境界に察しおチェックされたす。 倀が範囲倖の堎合、 System.IndexOutOfRangeException がスロヌされ、それ以䞊の手順は実行されたせん。
    • 倉換されたむンデックス匏のオフセットにある文字列 P の文字の倀が、文字列アクセスの結果になりたす。

12.8.12.5 むンデクサヌ アクセス

むンデクサヌ アクセスの堎合、element_accessのprimary_expressionはクラス、構造䜓、たたはむンタヌフェむス型の倉数たたは倀であり、この型は、element_accessのargument_listに適甚できる 1 ぀以䞊のむンデクサヌを実装する必芁がありたす。 argument_listには、outたたはref匕数は含たれたせん。

フォヌムP[A]のむンデクサヌ アクセスのバむンド時凊理は、Pがクラス、構造䜓、たたはむンタヌフェむス型のTであり、Aがargument_listである堎合、次の手順で構成されたす。

  • T によっお提䟛されるむンデクサヌのセットが構築されたす。 セットは、Tで宣蚀されおいるすべおのむンデクサヌ、たたは宣蚀をオヌバヌラむドせず、珟圚のコンテキスト (§7.4) でアクセスできるTの基本型で構成されたす。
  • 察応可胜で他のむンデクサヌによっお非衚瀺にされおいないむンデクサヌにこのセットは瞮小されたす。 次の芏則は、セット内の各むンデクサヌ S.I に適甚されたす。ここで、 S はむンデクサヌ I が宣蚀されおいる型です。
    • I が A (§12.6.4.2) に察しお適甚できない堎合、 I はセットから削陀されたす。
    • I(A) に察しお が適甚される堎合、基本型の S で宣蚀されおいるすべおのむンデクサヌがセットから削陀されたす。
    • I(A)に察しお が適甚され、 S が object以倖のクラス型である堎合、むンタヌフェむスで宣蚀されおいるすべおのむンデクサヌがセットから削陀されたす。
  • 結果の候補むンデクサヌのセットが空の堎合、適甚可胜なむンデクサヌは存圚せず、バむンド時゚ラヌが発生したす。
  • 候補むンデクサヌのセットの最適なむンデクサヌは、 §12.6.4のオヌバヌロヌド解決芏則 䜿甚しお識別されたす。 1 ぀の最適なむンデクサヌを識別できない堎合、むンデクサヌのアクセスがあいたいになり、バむンド時゚ラヌが発生したす。
  • 最適なむンデクサヌのアクセサヌがチェックされたす。
    • むンデクサヌ アクセスが割り圓おのタヌゲットである堎合、むンデクサヌは set たたは ref get アクセサヌを持぀必芁がありたす。それ以倖の堎合は、バむンド時゚ラヌが発生したす。
    • それ以倖の堎合、むンデクサヌは get たたは ref get アクセサヌを持぀必芁がありたす。それ以倖の堎合は、バむンド時゚ラヌが発生したす。

むンデクサヌ アクセスの結果は、次のように分類されたす。

  • むンデクサヌに ref get アクセサヌがある堎合、結果はむンデクサヌ型の型が関連付けられた倉数になりたす。
  • それ以倖の堎合、結果はむンデクサヌ型の関連付けられた型を持぀倀になりたす。

Tがクラス型の堎合、関連付けられおいる型は、Tで開始し、基底クラスを怜玢するずきに芋぀かったむンデクサヌの最初の宣蚀たたはオヌバヌラむドから遞択されたす。 Tがむンタヌフェむス型の堎合、関連付けられた型は、Tおよびその盎接たたは間接的な基本むンタヌフェむスの䞭から、最も具䜓的な (§19.4.10) むンタヌフェむスにあるむンデクサヌの宣蚀たたはオヌバヌラむドから遞択されたす。 このような䞀意の型が存圚しない堎合は、コンパむル時゚ラヌです。

むンデクサヌ アクセスのランタむム凊理は、次の手順で構成されたす。

  • タヌゲット primary_expressionP が評䟡されたす。
  • argument_listAのむンデックス匏は、巊から右の順に評䟡されたす。
  • バむンディング時に決定された最適なむンデクサヌの䜿甚:
    • むンデクサヌ アクセスが割り圓おのタヌゲットである堎合は、set アクセサヌたたは ref get アクセサヌが呌び出され、新しい倀 (§12.24.2) が割り圓おられたす。
    • それ以倖の堎合は、get アクセサヌたたは ref get アクセサヌが呌び出され、珟圚の倀 (§12.2.2) が取埗されたす。

12.8.13 Null 条件付き芁玠アクセス

null_conditional_element_accessはprimary_expressionの埌に2぀のトヌクン "?" ず "[" が続き、その埌にargument_list、さらに"]" トヌクンが続きたす。そしお、0個以䞊のdependent_accessが続き、そのいずれもnull_forgiving_operatorが付けられるこずがありたす。

null_conditional_element_access
    : primary_expression '?' '[' argument_list ']'
      (null_forgiving_operator? dependent_access)*
    ;

null_conditional_element_accessのargument_listには、outたたはref匕数は含たれたせん。

null_conditional_element_accessのprimary_expressionは、array_initializerを含たない限り、array_creation_expressionにはなりたせん。たた、stackalloc_initializerを含たない限り、stackalloc_expressionにもなりたせん。

泚: この制限は、混乱を招く可胜性のあるコヌドを犁止するために存圚したす。 陀倖察象の䟋が芋぀かる element_access (§12.8.12) にも同様の制限が適甚されたす。 泚釈

null_conditional_element_access は、 element_access (§12.8.7) の条件付きバヌゞョンであり、結果の型が voidである堎合はバむンディング時間゚ラヌです。 結果の型が void である可胜性がある null 条件匏に぀いおは、(§12.8.11)を参照しおください。

null_conditional_element_access 匏 E は P?[A]B 圢匏で、B は、dependent_access になりたす (該圓する堎合)。 E の意味は次のように決定されたす。

  • P の型が null 蚱容倀型の堎合:

    匏 Tの型ずしお P.Value[A]B を定矩したしょう。

    • T が参照型たたは null 非蚱容倀型のいずれでもない型パラメヌタヌである堎合、コンパむル時゚ラヌが発生したす。

    • T が null 非蚱容倀型の堎合、 E の型は T?され、 E の意味は次の意味ず同じです。

      ((object)P == null) ? (T?)null : P.Value[A]B
      

      ただし、 P が評䟡されるのは 1 回だけです。

    • それ以倖の堎合、 E の型は Tずなり、 E の意味は次の意味ず同じになりたす。

      ((object)P == null) ? null : P.Value[A]B
      

      ただし、 P が評䟡されるのは 1 回だけです。

  • それ以倖の堎合:

    匏 Tの型ずしお P[A]B を定矩したしょう。

    • T が参照型たたは null 非蚱容倀型のいずれでもない型パラメヌタヌである堎合、コンパむル時゚ラヌが発生したす。

    • T が null 非蚱容倀型の堎合、 E の型は T?され、 E の意味は次の意味ず同じです。

      ((object)P == null) ? (T?)null : P[A]B
      

      ただし、 P が評䟡されるのは 1 回だけです。

    • それ以倖の堎合、 E の型は Tずなり、 E の意味は次の意味ず同じになりたす。

      ((object)P == null) ? null : P[A]B
      

      ただし、 P が評䟡されるのは 1 回だけです。

泚意: 次の圢匏の匏においお:

P?[A₀]?[A₁]

P が null に評䟡される堎合、A₀ も A₁ も評䟡されたせん。 匏がnull_conditional_element_accessたたはnull_conditional_member_access§12.8.8の操䜜を含む䞀連のものである堎合も同様です。

泚釈

12.8.14 このアクセス

this_access はキヌワヌド thisで構成されたす。

this_access
    : 'this'
    ;

this_access は、むンスタンス コンストラクタヌ、むンスタンス メ゜ッド、むンスタンス アクセサヌ (§12.2.1)、たたはファむナラむザヌの ブロック でのみ蚱可されたす。 次のいずれかの意味がありたす。

  • クラスのむンスタンス コンストラクタヌ内の this で を䜿甚するず、倀ずしお分類されたす。 倀の型は、䜿甚法が発生するクラスのむンスタンス型 (§15.3.2) であり、倀は構築されるオブゞェクトぞの参照です。
  • クラスのむンスタンス メ゜ッドたたはむンスタンス アクセサヌ内の this で を䜿甚するず、倀ずしお分類されたす。 倀の型は、䜿甚法が発生するクラスのむンスタンス型 (§15.3.2) であり、倀はメ゜ッドたたはアクセサヌが呌び出されたオブゞェクトぞの参照です。
  • 構造䜓のむンスタンス コンストラクタヌ内の this で を䜿甚するず、倉数ずしお分類されたす。 倉数の型は、䜿甚が行われる構造䜓のむンスタンス型 (§15.3.2) であり、倉数は構築される構造䜓を衚したす。
    • コンストラクタヌ宣蚀にコンストラクタヌ初期化子がない堎合、 this 倉数は構造䜓型の出力パラメヌタヌず同様に動䜜したすが、明確な代入芁件 (§9.4.1) が満たされおいない堎合ぱラヌにならない点が異なりたす。 代わりに、次の凊理が行われたす。
      • this倉数自䜓が芁件を満たしおいない堎合、コンストラクタヌ内の他のコヌドが実行される前に、芁件に違反するすべおの時点で、this内のすべおの未割り圓おむンスタンス倉数が初期化フェヌズで既定倀 (§9.3) に暗黙的に初期化されたす。
      • 内のむンスタンス倉数 this が芁件を満たしおいない堎合、たたは v 内の任意のレベルの入れ子のむンスタンス倉数が芁件を満たしおいない堎合、v は、コンストラクタヌ内の他のコヌドが実行される前に、初期化フェヌズで暗黙的に既定倀に初期化されたす。
    • それ以倖の堎合、 this 倉数は構造䜓型の ref パラメヌタヌずたったく同じように動䜜したす。 特に、これは倉数が最初に割り圓おられたず芋なされるこずを意味したす。
  • 構造䜓のむンスタンス メ゜ッドたたはむンスタンス アクセサヌ内の this で を䜿甚するず、倉数ずしお分類されたす。 倉数の型は、䜿甚が行われる構造䜓のむンスタンス型 (§15.3.2) です。
    • メ゜ッドたたはアクセサヌが反埩子 (§15.15) たたは非同期関数 (§15.14) でない堎合、 this 倉数はメ゜ッドたたはアクセサヌが呌び出された構造䜓を衚したす。
      • 構造䜓が readonly structの堎合、 this 倉数は構造䜓型の入力パラメヌタヌずたったく同じように動䜜したす
      • それ以倖の堎合、 this 倉数は構造䜓型の ref パラメヌタヌずたったく同じように動䜜したす。
    • メ゜ッドたたはアクセサヌが反埩子たたは非同期関数の堎合、 this 倉数は、メ゜ッドたたはアクセサヌが呌び出された構造䜓の コピヌ を衚し、構造䜓型の 倀 パラメヌタヌずたったく同じように動䜜したす。

䞊蚘のコンテキスト以倖のコンテキストで this で を䜿甚するず、コンパむル時゚ラヌになりたす。 特に、静的メ゜ッド、静的プロパティ アクセサヌ、たたはフィヌルド宣蚀の this で を参照するこずはできたせん。

12.8.15 ベヌス アクセス

base_access は、「base」トヌクンたたは識別子のいずれかが続くキヌワヌド . で構成され、オプションの type_argument_list たたは argument_list は、角かっこで囲たれたす。

base_access
    : 'base' '.' identifier type_argument_list?
    | 'base' '[' argument_list ']'
    ;

base_access は、珟圚のクラスたたは構造䜓の同様の名前付きメンバヌによっお非衚瀺になっおいる基底クラスのメンバヌにアクセスするために䜿甚されたす。 base_access は、むンスタンス コンストラクタヌ、むンスタンス メ゜ッド、むンスタンス アクセサヌ (§12.2.1)、たたはファむナラむザヌの本䜓でのみ蚱可されたす。 クラスたたは構造䜓で base.I が発生した堎合、I はそのクラスたたは構造䜓の基底クラスのメンバヌを衚す必芁がありたす。 同様に、クラスで base[E] が発生した堎合、適甚可胜なむンデクサヌが基底クラスに存圚する必芁がありたす。

バむンド時に、フォヌム ず base.I の base[E] 匏は、 ((B)this).I ず ((B)this)[E]が蚘述された堎合ずたったく同じように評䟡されたす。ここで、 B はコンストラクトが発生するクラスたたは構造䜓の基底クラスです。 したがっお、 base.I ず base[E] は this.I ず this[E]に察応したす。ただし、 this は基底クラスのむンスタンスず芋なされたす。

base_access が仮想関数メンバヌ (メ゜ッド、プロパティ、たたはむンデクサヌ) を参照するず、実行時に呌び出す関数メンバヌ (§12.6.6) の決定が倉曎されたす。 呌び出される関数メンバヌは、 に関しお関数メンバヌの最も掟生した実装 (B) を芋぀けるこずによっお決定されたす (thisの実行時の型に関しおは、非基本アクセスの堎合ず同様)。 したがっお、仮想関数メンバヌのオヌバヌラむド内で、 base_access を䜿甚しお、関数メンバヌの継承された実装を呌び出すこずができたす。 base_access によっお参照される関数メンバヌが抜象である堎合は、バむンド時゚ラヌが発生したす。

泚意: thisずは異なり、 base 自䜓は匏ではありたせん。 これは、 base_access たたは constructor_initializer (§15.11.2) のコンテキストでのみ䜿甚されるキヌワヌドです。 泚釈

12.8.16 埌眮むンクリメント挔算子ず埌眮デクリメント挔算子

post_increment_expression
    : primary_expression '++'
    ;

post_decrement_expression
    : primary_expression '--'
    ;

埌眮むンクリメントたたはデクリメント挔算のオペランドは、倉数、プロパティ アクセス、たたはむンデクサヌ アクセスずしお分類される匏でなければなりたせん。 挔算の結果はオペランドず同じ型の倀になりたす。

primary_expression がコンパむル時の型 dynamic を持぀堎合、挔算子は動的にバむンドされ (§12.3.3)、 post_increment_expression たたは post_decrement_expression はコンパむル時の型 dynamic を持ち、 primary_expression の実行時の型を䜿甚しお実行時に次の芏則が適甚されたす。

埌眮むンクリメントたたはデクリメント挔算のオペランドがプロパティたたはむンデクサヌ アクセスである堎合、プロパティたたはむンデクサヌには、get アクセサヌず set アクセサヌたたは init アクセサヌの䞡方が含たれたす。 そうでない堎合は、バむンド時゚ラヌが発生したす。

単項挔算子のオヌバヌロヌド解決(§12.4.4)は、特定の挔算子の実装を遞択するために適甚されたす。 定矩枈みの ++ 挔算子ず -- 挔算子は、 sbyte、 byte、 short、 ushort、 int、 uint、 nint、 nuint、 long、 ulong、 char、 floatdouble、 decimal、任意の列挙型に察しお存圚したす。 定矩枈みの ++ 挔算子は、オペランドに 1 を远加するこずによっお生成された倀を返し、定矩枈みの -- 挔算子は、オペランドから 1 を枛算するこずによっお生成された倀を返したす。 チェックされたコンテキストでは、この加算たたは枛算の結果が結果型の範囲倖で、結果の型が敎数型たたは列挙型の堎合、 System.OverflowException がスロヌされたす。

遞択した単項挔算子の戻り倀の型から primary_expressionの型ぞの暗黙的な倉換が必芁です。それ以倖の堎合は、コンパむル時゚ラヌが発生したす。

フォヌム x++ たたは x-- の埌眮むンクリメントたたはデクリメント挔算の実行時凊理は、次の手順で構成されたす。

  • x が倉数ずしお分類される堎合:
    • x は、倉数を生成するために評䟡されたす。
    • x の倀が保存されたす。
    • x の保存された倀は、遞択した挔算子のオペランド型に倉換され、この倀を匕数ずしお䜿甚しお挔算子が呌び出されたす。
    • 挔算子によっお返される倀は、 x の型に倉換され、 xの以前の評䟡によっお指定された堎所に栌玍されたす。
    • x の保存された倀が挔算の結果になりたす。
  • x がプロパティたたはむンデクサヌ アクセスずしお分類される堎合:
    • むンスタンス匏 (xがstaticされおいない堎合) ず、xに関連付けられおいる匕数リスト (xがむンデクサヌ アクセスの堎合) が評䟡され、その結果は埌続の get および set たたは init アクセサヌ呌び出しで䜿甚されたす。
    • x の get アクセサヌが呌び出され、戻り倀が保存されたす。
    • x の保存された倀は、遞択した挔算子のオペランド型に倉換され、この倀を匕数ずしお䜿甚しお挔算子が呌び出されたす。
    • 挔算子によっお返される倀は x の型に倉換され、 x の set アクセサヌたたは init アクセサヌは、その倀匕数ずしおこの倀を䜿甚しお呌び出されたす。
    • x の保存された倀が挔算の結果になりたす。

++挔算子ず--挔算子では、プレフィックス衚蚘もサポヌトされおいたす (§12.9.7)。 x++ たたは x-- の結果は挔算x の の倀ですが、 ++x たたは --x の結果は挔算x の の倀です。 どちらの堎合も、 x 自䜓は挔算埌に同じ倀を持ちたす。

挔算子 ++ たたは挔算子 -- 実装は、埌眮衚蚘たたはプレフィックス衚蚘を䜿甚しお呌び出すこずができたす。 2 ぀の衚蚘に察しお個別の挔算子を実装するこずはできたせん。

12.8.17 new 挔算子

12.8.17.1 党般

new 挔算子は、型の新しいむンスタンスを䜜成するために䜿甚されたす。

新しい匏には、次の 3 ぀の圢匏がありたす。

  • オブゞェクト䜜成匏は、クラス型ず倀型の新しいむンスタンスを䜜成するために䜿甚されたす。
  • 配列䜜成匏は、配列型の新しいむンスタンスを䜜成するために䜿甚されたす。
  • デリゲヌト䜜成匏は、デリゲヌト型のむンスタンスを取埗するために䜿甚されたす。

new 挔算子は、型のむンスタンスの䜜成を意味したすが、必ずしもメモリの割り圓おを意味するわけではありたせん。 特に、倀型のむンスタンスでは、存圚する倉数を超える远加のメモリは必芁ありたせん。たた、 new を䜿甚しお倀型のむンスタンスを䜜成するずきに割り圓おは行われたせん。

泚: デリゲヌト䜜成匏は、垞に新しいむンスタンスを䜜成するずは限りたせん。 匏がメ゜ッド グルヌプ倉換 (§10.8) たたは匿名関数倉換 (§10.7) ず同じ方法で凊理されるず、既存のデリゲヌト むンスタンスが再利甚される可胜性がありたす。 泚釈

12.8.17.2 オブゞェクト䜜成匏

12.8.17.2.1 党般

object_creation_expression は、 class_type たたは value_typeの新しいむンスタンスを䜜成するために䜿甚されたす。

object_creation_expression
    : 'new' type '(' argument_list? ')' object_or_collection_initializer?
    | 'new' type object_or_collection_initializer
    | target_typed_new
    ;

target_typed_new
    : 'new' '(' argument_list? ')' object_or_collection_initializer?
    ;

object_or_collection_initializer
    : object_initializer
    | collection_initializer
    ;

object_creation_expression の 型 は、 class_type、 value_type、 たたは type_parameterずしたす。 型 は、 tuple_type たたは抜象たたは静的な class_typeにするこずはできたせん。

䜿甚から type 掚論できる堎合は、 target_typed_newで蚱可されおいるように省略できたす。 型を掚論できない堎合、 type を省略するのはコンパむル時゚ラヌです。 target_typed_new匏には型がありたせん。 ただし、target_typed_new匏からすべおの型ぞの暗黙的なオブゞェクト䜜成倉換 (§10.2.19) がありたす。 target_typed_newが単項挔算子たたは二項挔算子のオペランドずしお䜿甚されおいる堎合、たたはオブゞェクト䜜成倉換の察象ではない堎合は、コンパむル時゚ラヌです。

typeが存圚する堎合は、その型Tしたす。それ以倖の堎合は、暗黙的な型Tしたす。

省略可胜な argument_list (§12.6.2) は、 型 が class_type たたは struct_typeである堎合にのみ蚱可されたす。

オブゞェクト䜜成匏は、オブゞェクト初期化子たたはコレクション初期化子を含む堎合、コンストラクタヌの匕数リストおよび括匧を省略できたす。 コンストラクタヌ匕数リストを省略し、かっこを囲むのは、空の匕数リストを指定するこずず同じです。

オブゞェクト初期化子たたはコレクション初期化子を含むオブゞェクト䜜成匏の凊理は、最初にむンスタンス コンストラクタヌを凊理しおから、オブゞェクト初期化子 (§12.8.17.2.2) たたはコレクション初期化子 (§12.8.17.2.3) で指定されたメンバヌたたは芁玠の初期化を凊理したす。

オプションの argument_list の匕数にコンパむル時の型 dynamic がある堎合、object_creation_expression は、動的にバむンドされ (§12.3.3)、次の芏則が、コンパむル時の型 がある dynamic の匕数のランタむム時の型を䜿甚しおランタむム時に適甚されたす。 ただし、オブゞェクトの䜜成では、 §12.6.5で説明されおいるように、コンパむル時のチェックが制限されたす。

フォヌム のバむンド時凊理 (指定された型たたは暗黙的な型new T(A)がTたたはvalue_typeであり、は省略可胜なA) は、次の手順で構成されたす。

  • T が value_type で、 A が存圚しない堎合:
    • Tが、明瀺的に宣蚀されたパラメヌタヌなしのむンスタンス コンストラクタヌを持぀struct_typeである堎合、そのコンストラクタヌは候補ずなり、次に説明するようにオヌバヌロヌド解決によっお遞択されたす。
    • それ以倖の堎合、 object_creation_expression は既定のコンストラクタヌ呌び出しです。 object_creation_expression の結果は、型 Tの倀、぀たり、 Tで定矩されおいる の既定倀です。
  • それ以倖の堎合、 T が type_parameter で、 A が存圚しない堎合:
    • に倀型制玄たたはコンストラクタヌ制玄 (T) が指定されおいない堎合、バむンド時゚ラヌが発生したす。
    • object_creation_expression の結果は、型パラメヌタヌがバむンドされおいるランタむム型の倀、぀たり、その型の既定のコンストラクタヌを呌び出した結果です。 実行時の型には、参照型たたは倀型を指定できたす。
  • それ以倖の堎合、 T が class_type たたは struct_typeの堎合:
    • T が抜象たたは静的な class_typeの堎合は、コンパむル時゚ラヌが発生したす。
    • 呌び出すむンスタンス コンストラクタヌは、 §12.6.4のオヌバヌロヌド解決芏則 䜿甚しお決定されたす。 候補むンスタンス コンストラクタヌのセットは、Tで宣蚀されおいるすべおのアクセス可胜なむンスタンス コンストラクタヌで構成されたす。このコンストラクタヌは、A (§12.6.4.2) に適甚されたす。 候補のむンスタンス コンストラクタヌのセットが空の堎合、たたは 1 ぀の最適なむンスタンス コンストラクタヌを識別できない堎合は、バむンド時゚ラヌが発生したす。
    • object_creation_expression の結果は、 T型の倀、぀たり、䞊蚘の手順で決定されたむンスタンス コンストラクタヌを呌び出すこずによっお生成される倀です。
    • それ以倖の堎合、 object_creation_expression は無効であり、バむンド時゚ラヌが発生したす。

object_creation_expression が動的にバむンドされおいる堎合でも、コンパむル時の型は Tです。

指定たたは暗黙的な型のたたはstruct_typeで、new T(A)が省略可胜なargument_listであるフォヌム Tのの実行時凊理は、次の手順で構成されたすA。

  • T が class_typeの堎合:
    • クラス T の新しいむンスタンスが割り圓おられたす。 新しいむンスタンスを割り圓おるのに十分なメモリがない堎合は、 System.OutOfMemoryException がスロヌされ、それ以䞊の手順は実行されたせん。
    • 新しいむンスタンスのすべおのフィヌルドは、既定倀 (§9.3) に初期化されたす。
    • むンスタンス コンストラクタヌは、関数メンバヌ呌び出し (§12.6.6) の芏則に埓っお呌び出されたす。 新しく割り圓おられたむンスタンスぞの参照がむンスタンス コンストラクタヌに自動的に枡され、このコンストラクタヌ内からむンスタンスにアクセスできたす。
  • T が struct_typeの堎合:
    • T 型のむンスタンスは、䞀時ロヌカル倉数を割り圓おるこずによっお䜜成されたす。 struct_type のむンスタンス コンストラクタヌは、䜜成するむンスタンスの各フィヌルドに倀を確実に割り圓おる必芁があるため、䞀時倉数の初期化は必芁ありたせん。
    • むンスタンス コンストラクタヌは、関数メンバヌ呌び出し (§12.6.6) の芏則に埓っお呌び出されたす。 新しく割り圓おられたむンスタンスぞの参照がむンスタンス コンストラクタヌに自動的に枡され、このコンストラクタヌ内からむンスタンスにアクセスできたす。
12.8.17.2.2 オブゞェクト初期化子

オブゞェクト初期化子 は、オブゞェクトの 0 個以䞊のフィヌルド、プロパティ、たたはむンデックス付き芁玠の倀を指定したす。

object_initializer
    : '{' member_initializer_list? '}'
    | '{' member_initializer_list ',' '}'
    ;

member_initializer_list
    : member_initializer (',' member_initializer)*
    ;

member_initializer
    : initializer_target '=' 'ref'? initializer_value
    ;

initializer_target
    : identifier
    | '[' argument_list ']'
    ;

initializer_value
    : 'ref'? expression
    | object_or_collection_initializer
    ;

オブゞェクト初期化子は、メンバヌ初期化子のシヌケンスで構成され、 { トヌクンず } トヌクンで囲み、コンマで区切られたす。 各 member_initializer は、初期化のタヌゲットを指定する必芁がありたす。 識別子 は、初期化するオブゞェクトのアクセス可胜なフィヌルドたたはプロパティに名前を付けたすが、角かっこで囲たれた argument_list は、初期化するオブゞェクトのアクセス可胜なむンデクサヌの匕数を指定する必芁がありたす。 オブゞェクト初期化子が同じフィヌルドたたはプロパティに察しお耇数のメンバヌ初期化子を含めるのぱラヌです。

泚: オブゞェクト初期化子は、同じフィヌルドたたはプロパティを耇数回蚭定するこずは蚱可されおいたせんが、むンデクサヌにはこのような制限はありたせん。 オブゞェクト初期化子には、むンデクサヌを参照する耇数の初期化子タヌゲットを含め、同じむンデクサヌ匕数を耇数回䜿甚するこずもできたす。 泚釈

各 initializer_target の埌に等号ず、匏、オブゞェクト初期化子、たたはコレクション初期化子が続きたす。 オブゞェクト初期化子内の匏で、初期化䞭の新しく䜜成されたオブゞェクトを参照するこずはできたせん。

initializer_targetのargument_listでは、Range型 (§18.4.3) の匕数は暗黙的にサポヌトされたせん。

等号の埌に匏を指定するメンバヌ初期化子は、タヌゲットぞの代入 (§12.24.2) ず同じ方法で凊理されたす。

等号の埌にオブゞェクト初期化子を指定するメンバヌ初期化子は、 入れ子になったオブゞェクト初期化子です。぀たり、埋め蟌みオブゞェクトの初期化です。 フィヌルドたたはプロパティに新しい倀を割り圓おる代わりに、入れ子になったオブゞェクト初期化子の割り圓おは、フィヌルドたたはプロパティのメンバヌぞの割り圓おずしお扱われたす。 入れ子になったオブゞェクト初期化子は、倀型のプロパティや、倀型を持぀読み取り専甚フィヌルドには適甚できたせん。

等号の埌にコレクション初期化子を指定するメンバヌ初期化子は、埋め蟌みコレクションの初期化です。 タヌゲット フィヌルド、プロパティ、たたはむンデクサヌに新しいコレクションを割り圓おる代わりに、初期化子で指定された芁玠がタヌゲットによっお参照されるコレクションに远加されたす。 タヌゲットは、 §12.8.17.2.3 で指定された芁件を満たすコレクション型である必芁がありたす。

初期化子タヌゲットがむンデクサヌを参照する堎合、むンデクサヌの匕数は垞に 1 回だけ評䟡されたす。 したがっお、匕数が䜿甚されおいなくおも (たずえば、ネストされた初期化子が空のため)、副次的圱響が評䟡されたす。

䟋: 次のクラスは、2 ぀の座暙を持぀点を衚したす。

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

Point のむンスタンスは、次のように䜜成および初期化できたす。

Point a = new Point { X = 0, Y = 1 };

効果は以䞋ず同じです

Point __a = new Point();
__a.X = 0;
__a.Y = 1;
Point a = __a;

ここで、 __a はそれ以倖の堎合は非衚瀺でアクセスできない䞀時倉数です。

次のクラスは、2 ぀のポむントから䜜成された四角圢ず、 Rectangle むンスタンスの䜜成ず初期化を瀺しおいたす。

public class Rectangle
{
    public Point P1 { get; set; }
    public Point P2 { get; set; }
}

Rectangle のむンスタンスは、次のように䜜成および初期化できたす。

Rectangle r = new Rectangle
{
    P1 = new Point { X = 0, Y = 1 },
    P2 = new Point { X = 2, Y = 3 }
};

効果は以䞋ず同じです

Rectangle __r = new Rectangle();
Point __p1 = new Point();
__p1.X = 0;
__p1.Y = 1;
__r.P1 = __p1;
Point __p2 = new Point();
__p2.X = 2;
__p2.Y = 3;
__r.P2 = __p2;
Rectangle r = __r;

ここで、 __r、 __p1 および __p2 は、それ以倖の堎合は非衚瀺でアクセスできない䞀時的な倉数です。

Rectangleのコンストラクタヌが 2 ぀の埋め蟌み Point むンスタンスを割り圓おる堎合は、新しいむンスタンスを割り圓おるのではなく、埋め蟌み Point むンスタンスを初期化するために䜿甚できたす。

public class Rectangle
{
    public Point P1 { get; } = new Point();
    public Point P2 { get; } = new Point();
}

次のコンストラクトを䜿甚しお、新しいむンスタンスを割り圓おる代わりに、埋め蟌み Point むンスタンスを初期化できたす。

Rectangle r = new Rectangle
{
    P1 = { X = 0, Y = 1 },
    P2 = { X = 2, Y = 3 }
};

効果は以䞋ず同じです

Rectangle __r = new Rectangle();
__r.P1.X = 0;
__r.P1.Y = 1;
__r.P2.X = 2;
__r.P2.Y = 3;
Rectangle r = __r;

終了サンプル

12.8.17.2.3 コレクション初期化子

コレクション初期化子は、コレクションの芁玠を指定したす。

collection_initializer
    : '{' element_initializer_list '}'
    | '{' element_initializer_list ',' '}'
    ;

element_initializer_list
    : element_initializer (',' element_initializer)*
    ;

element_initializer
    : non_assignment_expression
    | '{' expression_list '}'
    ;

expression_list
    : expression (',' expression)*
    ;

コレクション初期化子は、芁玠初期化子のシヌケンスで構成され、 { トヌクンず } トヌクンで囲み、コンマで区切られたす。 各芁玠初期化子は、初期化するコレクション オブゞェクトに远加する芁玠を指定し、 { トヌクンず } トヌクンで囲たれた匏の䞀芧で構成され、コンマで区切られたす。 単䞀匏芁玠初期化子は䞭括匧を䜿わずに蚘述できたすが、メンバヌ初期化子ずの混同を避けるために代入匏にはできたせん。 non_assignment_expression生産は §12.25 で定矩されおいたす。

䟋: コレクション初期化子を含むオブゞェクト䜜成匏の䟋を次に瀺したす。

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

終了サンプル

コレクション初期化子が適甚されるコレクション オブゞェクトは、 System.Collections.IEnumerable を実装する型であるか、コンパむル時゚ラヌが発生したす。 指定された芁玠ごずに、巊から右の順序で、通垞のメンバヌ怜玢が適甚され、 Addずいう名前のメンバヌが怜玢されたす。 メンバヌ怜玢の結果がメ゜ッド グルヌプでない堎合は、コンパむル時゚ラヌが発生したす。 それ以倖の堎合は、芁玠初期化子の匏リストを匕数リストずしおオヌバヌロヌド解決が適甚され、コレクション初期化子によっお結果のメ゜ッドが呌び出されたす。 したがっお、コレクション オブゞェクトには、各芁玠初期化子の名前 Add を持぀適甚可胜なむンスタンスたたは拡匵メ゜ッドが含たれおいる必芁がありたす。

䟋: 名前ず電話番号の䞀芧を持぀連絡先を衚すクラスず、List<Contact>の䜜成ず初期化を次に瀺したす。

public class Contact
{
    public string Name { get; set; }
    public List<string> PhoneNumbers { get; } = new List<string>();
}

class A
{
    static void M()
    {
        var contacts = new List<Contact>
        {
            new Contact
            {
                Name = "Chris Smith",
                PhoneNumbers = { "206-555-0101", "425-882-8080" }
            },
            new Contact
            {
                Name = "Bob Harris",
                PhoneNumbers = { "650-555-0199" }
            }
        };
    }
}

次ず同じ効果を持぀

var __clist = new List<Contact>();
Contact __c1 = new Contact();
__c1.Name = "Chris Smith";
__c1.PhoneNumbers.Add("206-555-0101");
__c1.PhoneNumbers.Add("425-882-8080");
__clist.Add(__c1);
Contact __c2 = new Contact();
__c2.Name = "Bob Harris";
__c2.PhoneNumbers.Add("650-555-0199");
__clist.Add(__c2);
var contacts = __clist;

ここで、 __clist、 __c1 および __c2 は、それ以倖の堎合は非衚瀺でアクセスできない䞀時的な倉数です。

終了サンプル

12.8.17.3 匿名オブゞェクト䜜成匏

anonymous_object_creation_expression は、匿名型のオブゞェクトを䜜成するために䜿甚されたす。

anonymous_object_creation_expression
    : 'new' anonymous_object_initializer
    ;

anonymous_object_initializer
    : '{' member_declarator_list? '}'
    | '{' member_declarator_list ',' '}'
    ;

member_declarator_list
    : member_declarator (',' member_declarator)*
    ;

member_declarator
    : simple_name
    | member_access
    | null_conditional_projection_initializer
    | base_access
    | identifier '=' expression
    ;

匿名オブゞェクト初期化子は匿名型を宣蚀し、その型のむンスタンスを返したす。 匿名型は、 objectから盎接継承する名前のないクラス型です。 匿名型のメンバヌは、型のむンスタンスを䜜成するために䜿甚される匿名オブゞェクト初期化子から掚論される読み取り専甚プロパティのシヌケンスです。 具䜓的には、フォヌムの匿名オブゞェクト初期化子

new { p₁=e₁,p₂=e₂, 
 pv=ev}

フォヌムの匿名型を宣蚀したす

class __Anonymous1
{
    private readonly «T1» «f1»;
    private readonly «T2» «f2»;
    ...
    private readonly «Tn» «fn»;

    public __Anonymous1(«T1» «a1», «T2» «a2»,..., «Tn» «an»)
    {
        «f1» = «a1»;
        «f2» = «a2»;
        ...
        «fn» = «an»;
    }

    public «T1» «p1» { get { return «f1»; } }
    public «T2» «p2» { get { return «f2»; } }
    ...
    public «Tn» «pn» { get { return «fn»; } }
    public override bool Equals(object __o) { ... }
    public override int GetHashCode() { ... }
}

ここで、各 «Tx» は、察応する匏 «ex» の型です。 member_declarator で䜿甚される匏は型を持぀必芁がありたす。 したがっお、 member_declarator 内の匏が null たたは匿名関数のコンパむル時゚ラヌになりたす。

匿名型の名前ずその Equals メ゜ッドのパラメヌタヌは、コンパむラによっお自動的に生成され、プログラム テキストでは参照できたせん。

同じプログラム内で、同じ名前ずコンパむル時の型の䞀連のプロパティを同じ順序で指定する 2 ぀の匿名オブゞェクト初期化子は、同じ匿名型のむンスタンスを生成したす。

䟋: この䟋では

var p1 = new { Name = "Lawnmower", Price = 495.00 };
var p2 = new { Name = "Shovel", Price = 26.95 };
p1 = p2;

p1 ず p2 が同じ匿名型であるため、最埌の行の割り圓おが蚱可されたす。

終了サンプル

匿名型の Equals メ゜ッドず GetHashcode メ゜ッドは、 objectから継承されたメ゜ッドをオヌバヌラむドし、プロパティの Equals ず GetHashcode の芳点から定矩されるため、同じ匿名型の 2 ぀のむンスタンスは、すべおのプロパティが等しい堎合にのみ等しくなりたす。

メンバヌ宣蚀子は、単玔な名前 (§12.8.4)、メンバヌ アクセス (§12.8.7)、null 条件付きプロゞェクション初期化子 §12.8.8 たたはベヌス アクセス (§12.8.15) に省略できたす。 これは、 プロゞェクション初期化子 ず呌ばれ、同じ名前のプロパティの宣蚀ず割り圓おの短瞮圢です。 具䜓的には、圢匏のメンバヌ宣蚀子

«identifier»、 «expr» . «identifier» および «expr» ? . «identifier»

は、それぞれ次ずたったく同じです。

«identifier» = «identifier»、 «identifier» = «expr» . «identifier» および «identifier» = «expr» ? . «identifier»

したがっお、プロゞェクション初期化子では、識別子は倀ず、倀が割り圓おられおいるフィヌルドたたはプロパティの䞡方を遞択したす。 盎感的に、プロゞェクション初期化子は倀だけでなく、倀の名前も投圱したす。

12.8.17.4 配列䜜成匏

array_creation_expression は、 array_typeの新しいむンスタンスを䜜成するために䜿甚されたす。

array_creation_expression
    : 'new' non_array_type '[' expression_list ']' rank_specifier*
      array_initializer?
    | 'new' array_type array_initializer
    | 'new' rank_specifier array_initializer
    ;

最初のフォヌムの配列䜜成匏は、匏リストから個々の匏を削陀した結果ずしお生じる型の配列むンスタンスを割り圓おたす。

    䟋: 配列䜜成匏 new int[10,20] は型 int[,] の配列むンスタンスを生成し、配列䜜成匏 new int[10][,] は型 int[][,] の配列むンスタンスを生成したす。 終了サンプル

匏リスト内の各匏は、 int、 uint、 long、たたは ulongの型であるか、たたはこれらの型の 1 ぀以䞊に暗黙的に倉換可胜である必芁がありたす。 各匏の倀によっお、新しく割り圓おられた配列むンスタンス内の察応するディメンションの長さが決たりたす。 配列次元の長さは負の倀でないため、匏リスト内で負の倀を持぀定数匏を持぀こずはコンパむル時゚ラヌです。

安党でないコンテキスト (§24.2) を陀き、配列のレむアりトは指定されおいたせん。

最初の圢匏の配列䜜成匏に配列初期化子が含たれおいる堎合、匏リスト内の各匏は定数で、匏リストで指定されたランクず次元の長さは配列初期化子の長さず䞀臎する必芁がありたす。

2 番目たたは 3 番目の圢匏の配列䜜成匏では、指定された配列型たたはランク指定子のランクは、配列初期化子のランクず䞀臎する必芁がありたす。 個々の次元の長さは、配列初期化子の察応する入れ子レベルの芁玠の数から掚論されたす。 したがっお、次の宣蚀における初期化子匏

var a = new int[,] {{0, 1}, {2, 3}, {4, 5}};

ず正確に䞀臎したす。

var a = new int[3, 2] {{0, 1}, {2, 3}, {4, 5}};

3 番目の圢匏の配列䜜成匏は、 暗黙的に型指定された配列䜜成匏ず呌ばれたす。 これは、配列の芁玠型が明瀺的に指定されおいないが、配列初期化子の匏セットの最も䞀般的な型 (§12.6.3.17) ずしお決定されるこずを陀いお、2 番目の圢匏に䌌おいたす。 倚次元配列 (぀たり、 rank_specifier に少なくずも 1 ぀のコンマが含たれる配列) の堎合、このセットは、入れ子になった array_initializerで芋぀かったすべおの 匏で構成されたす。

配列初期化子に぀いおは、 §17.7で詳しく説明したす。

配列䜜成匏を評䟡した結果は、倀、぀たり新しく割り圓おられた配列むンスタンスぞの参照ずしお分類されたす。 配列䜜成匏の実行時凊理は、次の手順で構成されたす。

  • expression_list の次元の長さの匏は、巊から右の順に評䟡されたす。 各むンデックス匏の評䟡の埌、暗黙的な倉換 (§10.2) を次のいずれかの型に倉換したす。 int、 uint、 long、 ulong。 暗黙的な倉換が存圚するこのリストの最初の型が遞択されたす。 匏の評䟡たたはその埌の暗黙的な倉換によっお䟋倖が発生した堎合、それ以䞊の匏は評䟡されたせん。それ以䞊の手順は実行されたせん。
  • ディメンションの長さの蚈算倀は、次のように怜蚌されたす。1 ぀以䞊の倀が 0 未満の堎合、 System.OverflowException がスロヌされ、それ以䞊の手順は実行されたせん。
  • 指定された次元の長さを持぀配列むンスタンスが割り圓おられたす。 新しいむンスタンスを割り圓おるのに十分なメモリがない堎合は、 System.OutOfMemoryException がスロヌされ、それ以䞊の手順は実行されたせん。
  • 新しい配列むンスタンスのすべおの芁玠は、既定倀 (§9.3) に初期化されたす。
  • 配列䜜成匏に配列初期化子が含たれおいる堎合、配列初期化子内の各匏が評䟡され、察応する配列芁玠に割り圓おられたす。 評䟡ず代入は、匏が配列初期化子に曞き蟌たれる順序で実行されたす。぀たり、芁玠はむンデックスの順序を増やしお初期化され、右端の次元が最初に増加したす。 特定の匏の評䟡たたは察応する配列芁玠ぞの埌続の代入によっお䟋倖が発生した堎合、それ以䞊の芁玠は初期化されたせん (そのため、残りの芁玠には既定倀が蚭定されたす)。

配列䜜成匏では、配列型の芁玠を含む配列のむンスタンス化が可胜ですが、このような配列の芁玠は手動で初期化する必芁がありたす。

䟋の: ステヌトメント

int[][] a = new int[100][];

は、 int[]型の 100 個の芁玠を持぀ 1 次元配列を䜜成したす。 各芁玠の初期倀は nullです。 同じ配列䜜成匏でサブ配列ずステヌトメントをむンスタンス化するこずはできたせん。

int[][] a = new int[100][5]; // Error

の堎合、コンパむル時゚ラヌが発生したす。 サブ配列のむンスタンス化は、次のように手動で実行できたす。

int[][] a = new int[100][];
for (int i = 0; i < 100; i++)
{
    a[i] = new int[5];
}

終了サンプル

泚: 配列の配列に "四角圢" の図圢がある堎合、぀たりサブ配列がすべお同じ長さの堎合は、倚次元配列を䜿甚する方が効率的です。 䞊蚘の䟋では、配列の配列をむンスタンス化するず、101 個のオブゞェクト (1 ぀の倖偎の配列ず 100 個のサブ配列) が䜜成されたす。 それに察しお

int[,] a = new int[100, 5];

では、1 ぀のオブゞェクト (2 次元配列) のみが䜜成され、1 ぀のステヌトメントで割り圓おが実行されたす。

泚釈

䟋: 暗黙的に型指定された配列䜜成匏の䟋を次に瀺したす。

var a = new[] { 1, 10, 100, 1000 };                     // int[]
var b = new[] { 1, 1.5, 2, 2.5 };                       // double[]
var c = new[,] { { "hello", null }, { "world", "!" } }; // string[,]
var d = new[] { 1, "one", 2, "two" };                   // Error

最埌の匏では、int も string も互いに暗黙的に倉換するこずができないため、最適な共通型が存圚せず、コンパむル時゚ラヌが発生したす。 この堎合は、明瀺的に型指定された配列䜜成匏を䜿甚する必芁がありたす。たずえば、 object[]する型を指定したす。 たたは、いずれかの芁玠を共通の基本型にキャストしお、掚論される芁玠型にするこずができたす。

終了サンプル

暗黙的に型指定された配列䜜成匏を匿名オブゞェクト初期化子 (§12.8.17.3) ず組み合わせお、匿名型のデヌタ構造を䜜成できたす。

䟋:

var contacts = new[]
{
    new
    {
        Name = "Chris Smith",
        PhoneNumbers = new[] { "206-555-0101", "425-882-8080" }
    },
    new 
    {
        Name = "Bob Harris",
       PhoneNumbers = new[] { "650-555-0199" }
    }
};

終了サンプル

12.8.17.5 デリゲヌト䜜成匏

delegate_creation_expression は、 delegate_typeのむンスタンスを取埗するために䜿甚されたす。

delegate_creation_expression
    : 'new' delegate_type '(' expression ')'
    ;

デリゲヌト䜜成匏の匕数は、メ゜ッド グルヌプ、匿名関数、たたはコンパむル時の型 dynamic たたは delegate_typeのいずれかの倀になりたす。 匕数がメ゜ッド グルヌプの堎合は、メ゜ッドを識別し、むンスタンス メ゜ッドの堎合はデリゲヌトを䜜成するオブゞェクトを識別したす。 匕数が匿名関数の堎合、デリゲヌト タヌゲットのパラメヌタヌずメ゜ッド本䜓を盎接定矩したす。 匕数が倀の堎合、コピヌを䜜成するデリゲヌト むンスタンスを識別したす。

匏にコンパむル時の型dynamicがある堎合、delegate_creation_expressionは動的にバむンドされ (§12.8.17.5)、次の芏則は実行時に匏の実行時型を䜿甚しお適甚されたす。 それ以倖の堎合、ルヌルはコンパむル時に適甚されたす。

が D(E) および D が expression である圢匏new Eの delegate_creation_expression のバむンディング時の凊理は、次の手順で構成されたす。

  • E がメ゜ッド グルヌプの堎合、デリゲヌト䜜成匏は、メ゜ッド グルヌプ倉換 (§10.8) ず同じ方法で E から Dに凊理されたす。

  • E が匿名関数の堎合、デリゲヌト䜜成匏は、 から Eぞの匿名関数倉換 (D) ず同じ方法で凊理されたす。

  • Eが倀の堎合、Eはず互換性があり (D)、結果は、Eを呌び出す単䞀゚ントリ呌び出しリストを持぀新しく䜜成されたデリゲヌトぞの参照になりたす。

が D(E) および D が expression である圢匏new Eの delegate_creation_expression の実行時の凊理は、次の手順で構成されたす。

  • E がメ゜ッド グルヌプの堎合、デリゲヌト䜜成匏はメ゜ッド グルヌプ倉換 (§10.8) ずしお E から Dに評䟡されたす。
  • E が匿名関数の堎合、デリゲヌトの䜜成は、 E から D (§10.7) ぞの匿名関数倉換ずしお評䟡されたす。
  • E が delegate_typeの倀の堎合:
    • E が評䟡されたす。 この評䟡によっお䟋倖が発生した堎合、それ以䞊の手順は実行されたせん。
    • E の倀が nullの堎合、 System.NullReferenceException がスロヌされ、それ以䞊の手順は実行されたせん。
    • D デリゲヌト型の新しいむンスタンスが割り圓おられたす。 新しいむンスタンスを割り圓おるのに十分なメモリがない堎合は、 System.OutOfMemoryException がスロヌされ、それ以䞊の手順は実行されたせん。
    • 新しいデリゲヌト むンスタンスは、 Eを呌び出す単䞀゚ントリ呌び出しリストで初期化されたす。

デリゲヌトの呌び出しリストは、デリゲヌトがむンスタンス化されるずきに決定され、デリゲヌトの有効期間党䜓にわたっお䞀定のたたになりたす。 ぀たり、䜜成されたデリゲヌトのタヌゲット呌び出し可胜゚ンティティを倉曎するこずはできたせん。

泚意:2぀のデリゲヌトが結合されたずき、たたは1぀が別のデリゲヌトから削陀されたずき、新しいデリゲヌトの結果を芚えおおいおください。既存のデリゲヌトのコンテンツが倉曎されおいない。 泚釈

プロパティ、むンデクサヌ、ナヌザヌ定矩挔算子、むンスタンス コンストラクタヌ、ファむナラむザヌ、たたは静的コンストラクタヌを参照するデリゲヌトを䜜成するこずはできたせん。

䟋: 前述のように、デリゲヌトがメ゜ッド グルヌプから䜜成されるずきに、デリゲヌトのパラメヌタヌ リストず戻り倀の型によっお、どのオヌバヌロヌドされたメ゜ッドを遞択するかが決たりたす。 この䟋では

delegate double DoubleFunc(double x);

class A
{
    DoubleFunc f = new DoubleFunc(Square);

    static float Square(float x) => x * x;
    static double Square(double x) => x * x;
}

A.f フィヌルドは、2 番目の Square メ゜ッドを参照するデリゲヌトで初期化されたす。これは、そのメ゜ッドが DoubleFuncのパラメヌタヌ リストず戻り倀の型ず完党に䞀臎するためです。 2 番目の Square メ゜ッドが存圚しない堎合は、コンパむル時゚ラヌが発生した可胜性がありたす。

終了サンプル

12.8.18 typeof 挔算子

typeof 挔算子は、型の System.Type オブゞェクトを取埗するために䜿甚されたす。

typeof_expression
    : 'typeof' '(' type ')'
    | 'typeof' '(' unbound_type_name ')'
    | 'typeof' '(' 'void' ')'
    ;

unbound_type_name
    : identifier generic_dimension_specifier?
      ('.' identifier generic_dimension_specifier?)*
    | unbound_qualified_alias_member
      ('.' identifier generic_dimension_specifier?)*
    ;

unbound_qualified_alias_member
    : identifier '::' identifier generic_dimension_specifier?
    ;

generic_dimension_specifier
    : '<' comma* '>'
    ;

comma
    : ','
    ;

typeof_expression の最初の圢匏は、 typeof キヌワヌドの埌にかっこで囲たれた型で構成されたす。 この圢匏の匏の結果は、指定された型の System.Type オブゞェクトです。 特定の型に察しお System.Type オブゞェクトは 1 ぀だけ存圚したす。 ぀たり、 T型の堎合、 typeof(T) == typeof(T) は垞に true になりたす。 型を dynamicにするこずができたせん。

typeof_expression の 2 番目の圢匏は、 typeof キヌワヌドの埌にかっこで囲たれた unbound_type_nameで構成されたす。

泚: unbound_type_nameおよびunbound_qualified_alias_memberの文法は、type_name (§7.7) およびqualified_alias_member (§14.9.1) の文法に埓いたす。ただし、generic_dimension_specifierは type_argument_listに眮き換えられたす。 泚釈

typeof_expressionのオペランドを認識する際に、unbound_type_nameずtype_nameの䞡方が該圓し、generic_dimension_specifierおよびtype_argument_listを含たない堎合、type_nameが遞ばれなければなりたせん。

泚: ANTLR は、typeof_expressionの代替の順序により、指定された遞択を自動的に行いたす。 泚釈

unbound_type_nameの意味は、次のように決定されたす。

  • トヌクンのシヌケンスは、各generic_dimension_specifierを、各type_argumentず同じ数のコンマずキヌワヌド を持぀objectに眮き換えるこずによっお、type_nameに倉換されたす。
  • 結果の type_name は、構築された型 (§7.7) に解決されたす。
  • unbound_type_nameは、解決された構築型 (§8.4) に関連付けられた非連結ゞェネリック型です。

泚: トヌクンのシヌケンスを倉換する実装、たたは䞭間構築型を生成する必芁はありたせん。このプロセスに埓った堎合ず同じように、決定される非連結ゞェネリック型は "そのたた" です。 泚釈

型名が null 蚱容参照型であるこずぱラヌです。

typeof_expression の結果は、結果ずしお埗られる非連結ゞェネリック型の System.Type オブゞェクトです。

3 番目の圢匏の typeof_expression は、 typeof キヌワヌドの埌に、かっこで囲たれた void キヌワヌドで構成されたす。 このフォヌムの匏の結果は、型が存圚しないこずを衚す System.Type オブゞェクトです。 typeof(void) によっお返される型オブゞェクトは、任意の型に察しお返される型オブゞェクトずは異なりたす。

泚意: この特殊な System.Type オブゞェクトは、蚀語内のメ゜ッドぞのリフレクションを可胜にするクラス ラむブラリで圹立ちたす。これらのメ゜ッドは、void メ゜ッドを含む任意のメ゜ッドの戻り倀の型を System.Typeのむンスタンスで衚す方法を持぀こずを望みたす。 泚釈

typeof 挔算子は、型パラメヌタヌで䜿甚できたす。 型名が null 蚱容参照型であるこずがわかっおいれば、コンパむル時゚ラヌになりたす。 結果は、型パラメヌタヌにバむンドされたランタむム型の System.Type オブゞェクトです。 タンタむム時の型が null 蚱容参照型の堎合、結果は察応する null 非蚱容参照型になりたす。 typeof 挔算子は、構築された型たたはバむンドされおいないゞェネリック型 (§8.4.4) でも䜿甚できたす。 バむンドされおいないゞェネリック型の System.Type オブゞェクトは、むンスタンス型 (System.Type) の オブゞェクトず同じではありたせん。 むンスタンス型は実行時に垞に閉じた構築型であるため、その System.Type オブゞェクトは䜿甚䞭の実行時の型匕数に䟝存したす。 䞀方、バむンドされおいないゞェネリック型には型匕数がなく、ランタむム型匕数に関係なく同じ System.Type オブゞェクトが生成されたす。

䟋: その䟋

class X<T>
{
    public static void PrintTypes()
    {
        Type[] t =
        {
            typeof(int),
            typeof(System.Int32),
            typeof(string),
            typeof(double[]),
            typeof(void),
            typeof(T),
            typeof(X<T>),
            typeof(X<X<T>>),
            typeof(X<>)
        };
        for (int i = 0; i < t.Length; i++)
        {
            Console.WriteLine(t[i]);
        }
    }
}

class Test
{
    static void Main()
    {
        X<int>.PrintTypes();
    }
}

生成される出力は次のずおりです。

System.Int32
System.Int32
System.String
System.Double[]
System.Void
System.Int32
X`1[System.Int32]
X`1[X`1[System.Int32]]
X`1[T]

int ず System.Int32 は同じ型であるこずに泚意しおください。 typeof(X<>) の結果は型匕数に䟝存したせんが、 typeof(X<T>) の結果は䟝存したす。

終了サンプル

12.8.19 sizeof 挔算子

sizeof は、指定された型の倉数が占有しおいる8ビットバむトを返したす。

sizeof_expression
    : 'sizeof' '(' unmanaged_type ')'
    ;

特定の型の堎合、 sizeof 挔算子は、次の衚に瀺すように定数 int 倀を生成したす。

匏 結果
sizeof(sbyte) 1
sizeof(byte) 1
sizeof(short) 2
sizeof(ushort) 2
sizeof(int) 4
sizeof(uint) 4
sizeof(long) 8
sizeof(ulong) 8
sizeof(char) 2
sizeof(float) 4
sizeof(double) 8
sizeof(bool) 1
sizeof(decimal) 16

列挙型 Tの堎合、匏 sizeof(T) の結果は、䞊蚘のように、基になる型のサむズず等しい定数倀になりたす。

その他のすべおのオペランド型の堎合、 sizeof 挔算子は §24.6.9 で指定され、安党でないコンテキストでのみ䜿甚できたす。

12.8.20 チェック枈みおよび未チェックの挔算子

checked および unchecked 挔算子は、敎数型の算術挔算および倉換に察するオヌバヌフロヌ チェック コンテキストを制埡するために䜿甚したす。 たた、ナヌザヌ定矩型 (§15.10.1) に関連するさたざたな操䜜や倉換のオヌバヌフロヌ チェック コンテキストを制埡するためにも䜿甚できたす。

checked_expression
    : 'checked' '(' expression ')'
    ;

unchecked_expression
    : 'unchecked' '(' expression ')'
    ;

checked 挔算子は、チェックされたコンテキストに含たれおいる匏を評䟡し、 unchecked 挔算子は、チェックされおいないコンテキストに含たれおいる匏を評䟡したす。 checked_expression たたは unchecked_expression は、parenthesized_expression (§12.8.5) に正確に察応したすが、含たれる倀は、指定のオヌバヌフロヌ確認コンテキストで評䟡されたす。

オヌバヌフロヌ チェック コンテキストは、 checked および unchecked ステヌトメント (§13.12) を䜿甚しお制埡するこずもできたす。

次の挔算は、チェックされた挔算子ずチェックされおいない挔算子ずステヌトメントによっお確立されたオヌバヌフロヌ チェック コンテキストの圱響を受けたす。

  • オペランドが敎数型たたは列挙型の堎合、定矩枈みの++挔算子ず--挔算子 (§12.8.16 および §12.9.7)。
  • オペランドが敎数型の堎合、定矩枈みの - 単項挔算子 (§12.9.3)。
  • 䞡方のオペランドが敎数型たたは列挙型の堎合、定矩枈みの +、 -、 *、および / 二項挔算子 (§12.13)。
  • 1 ぀の敎数型たたは列挙型から別の敎数型たたは列挙型ぞの明瀺的な数倀倉換 (§10.3.2)、たたは float たたは double から敎数型たたは列挙型ぞの倉換。
  • オペランド型でチェックされた圢匏の挔算子が宣蚀されおいる堎合、ナヌザヌ定矩の ++、 --、単項 -、バむナリ +、 -、 *、および / 挔算子 (§15.10.1)。
  • ナヌザヌ定矩の明瀺的な倉換挔算子 (§15.10.4)。

䞊蚘のいずれかの挔算で結果が生成され、倉換先の型で衚すには倧きすぎる堎合、挔算が実行されるコンテキストによっお結果の動䜜が制埡されたす。

  • checkedコンテキストで、操䜜が定数匏 (§12.26) の堎合、コンパむル時゚ラヌが発生したす。 それ以倖の堎合は、実行時に挔算が実行されるず System.OverflowException がスロヌされたす。
  • unchecked コンテキストでは、結果の栌玍先の型に収たらない䞊䜍ビットが砎棄されお、結果が切り詰められたす。

たたはchecked挔算子たたはステヌトメントで囲たれおいない非定数匏 (unchecked) (実行時に評䟡される匏) の堎合、倖郚芁玠 (コンパむラ スむッチや実行環境構成など) がチェック評䟡を呌び出さない限り、既定のオヌバヌフロヌ チェック コンテキストはオフになりたす。

定数匏 (§12.26) (コンパむル時に完党に評䟡できる匏) の堎合、既定のオヌバヌフロヌ チェック コンテキストは垞にチェックされたす。 定数匏が unchecked コンテキストに明瀺的に配眮されおいない限り、匏のコンパむル時の評䟡䞭に発生するオヌバヌフロヌによっお、垞にコンパむル時゚ラヌが発生したす。

匿名関数の本䜓は、匿名関数が発生する checked たたは unchecked コンテキストの圱響を受けたせん。

䟋: 次のコヌド䟋の内容:

class Test
{
    static readonly int x = 1000000;
    static readonly int y = 1000000;

    static int F() => checked(x * y);    // Throws OverflowException
    static int G() => unchecked(x * y);  // Returns -727379968
    static int H() => x * y;             // Depends on default
}

どちらの匏もコンパむル時に評䟡できないので、コンパむル時゚ラヌは報告されたせん。 実行時に、 F メ゜ッドは System.OverflowExceptionをスロヌし、 G メ゜ッドは –727379968 (範囲倖の結果の䞋䜍 32 ビット) を返したす。 H メ゜ッドの動䜜は、コンパむルの既定のオヌバヌフロヌ チェック コンテキストに䟝存したすが、 F ず同じか、 Gず同じです。

終了サンプル

䟋: 次のコヌド䟋の内容:

class Test
{
    const int x = 1000000;
    const int y = 1000000;

    static int F() => checked(x * y);    // Compile-time error, overflow
    static int G() => unchecked(x * y);  // Returns -727379968
    static int H() => x * y;             // Compile-time error, overflow
}

F および H で定数匏を評䟡するずきに発生するオヌバヌフロヌにより、匏が checked コンテキストで評䟡されるため、コンパむル時゚ラヌが報告されたす。 オヌバヌフロヌは、 Gで定数匏を評䟡するずきにも発生したすが、評䟡は unchecked コンテキストで行われるため、オヌバヌフロヌは報告されたせん。

終了サンプル

checked 挔算子ず unchecked 挔算子は、"(" および ")" トヌクン内にテキストで含たれる挔算のオヌバヌフロヌ チェック コンテキストにのみ圱響したす。 挔算子は、含たれおいる匏を評䟡した結果ずしお呌び出される関数メンバヌには圱響したせん。

䟋: 次のコヌド䟋の内容:

class Test
{
    static int Multiply(int x, int y) => x * y;

    static int F() => checked(Multiply(1000000, 1000000));
}

F で checked を䜿甚しおも x * y の Multiply の評䟡には圱響しないため、 x * yは既定のオヌバヌフロヌ チェック コンテキストで評䟡されたす。

終了サンプル

unchecked 挔算子は、笊号付き敎数型の定数を 16 進衚蚘で蚘述する堎合に䟿利です。

䟋:

class Test
{
    public const int AllBits = unchecked((int)0xFFFFFFFF);
    public const int HighBit = unchecked((int)0x80000000);
}

䞊蚘の 16 進定数はどちらも uint型です。 定数は int 範囲倖であるため、 unchecked 挔算子を䜿甚しないず、 int にキャストするずコンパむル時゚ラヌが発生したす。

終了サンプル

泚意: checked 挔算子ず unchecked 挔算子ずステヌトメントを䜿甚するず、プログラマはいく぀かの数倀蚈算の特定の偎面を制埡できたす。 ただし、䞀郚の数倀挔算子の動䜜は、オペランドのデヌタ型によっお異なりたす。 たずえば、2぀の小数を乗算するず、明瀺的な非チェックコンテキスト内でもオヌバヌフロヌ時に垞に䟋倖が発生したす。 同様に、2 ぀の浮動小数点を乗算しおも、明瀺的にチェックされたコンストラクト内であっおも、オヌバヌフロヌ時に䟋倖が発生するこずはありたせん。 さらに、他の挔算子は、既定か明瀺的かに関係なく、チェック モヌドの圱響を受けたせん。 泚釈

12.8.21 既定倀匏

デフォルト倀匏は、型のデフォルト倀 (§9.3) を取埗するために䜿甚されたす。

default_value_expression
    : explicitly_typed_default
    | default_literal
    ;

explicitly_typed_default
    : 'default' '(' type ')'
    ;

default_literal
    : 'default'
    ;

default_literal は既定倀 (§9.3) を衚したす。 型はありたせんが、既定のリテラル倉換 (§10.2.16) を䜿甚しお任意の型に倉換できたす。

default_value_expressionの結果は、explicitly_typed_defaultの明瀺的な型の既定倀 (§9.3)、たたはdefault_value_expressionの倉換のタヌゲット型です。

型が次のいずれかである堎合、 default_value_expression は定数匏 (§12.26) です。

  • 参照型
  • 参照型ずしお知られおいる型パラメヌタヌ (§8.2);
  • sbyte、byte、short、ushort、int、uint、nint、nuint、long、ulong、char、float、double、decimal、bool、
  • あらゆる列挙型。

rv型の参照倉数フィヌルドTには、defaultの明瀺的な初期化子は含たれたせん。

泚: rvを䜿甚しおrv = defaultを初期化しようずするず、参照倉数はnullに蚭定されたせん。 代わりに、型 Tの既定倀を参照する (存圚しない可胜性がある) 参照の倀を蚭定しようずしたす。 泚釈

Sたたはの倀で必芁なメンバヌ リスト (default) を持぀構造䜓default(S)のむンスタンスを䜜成する堎合、必須メンバヌ蚭定は適甚されたせん。 ただし、パラメヌタヌなしのコンストラクタヌがなく、既定の構造䜓コンストラクタヌが䜿甚new S()堎合でも、Sで䜜成されたむンスタンスに察しおこのような蚭定が適甚されたす。

䟋: 以䞋を確認しおください。

S v1 = default;     // OK: no checking for required members
S v2 = default(S);  // OK: no checking for required members
S v3 = new S();     // error: required member must be set
S v4 = new S() { reqInt = default };  // OK: required member is set

public struct S
{
    public required int reqInt;
}

終了サンプル

12.8.22 スタック割り圓お

スタック割り圓お匏は、実行スタックからメモリ ブロックを割り圓おたす。 実行スタック は、ロヌカル倉数が栌玍されるメモリ領域です。 実行スタックはマネヌゞド ヒヌプの䞀郚ではありたせん。 ロヌカル倉数ストレヌゞに䜿甚されるメモリは、珟圚の関数が戻ったずきに自動的に回埩されたす。

スタック割り圓お匏の安党なコンテキスト芏則に぀いおは、 §16.8.15.10 を参照しおください。

stackalloc_expression
    : 'stackalloc' unmanaged_type '[' expression ']'
    | 'stackalloc' unmanaged_type? '[' constant_expression? ']' stackalloc_initializer
    ;

stackalloc_initializer
     : '{' stackalloc_initializer_element_list '}'
     ;

stackalloc_initializer_element_list
     : stackalloc_element_initializer (',' stackalloc_element_initializer)* ','?
     ;
    
stackalloc_element_initializer
    : expression
    ;

unmanaged_type (§8.8) は、新しく割り圓おられた堎所に栌玍される項目の皮類を瀺し、 匏 はこれらの項目の数を瀺したす。 これらを組み合わせお、必芁な割り圓おサむズを指定したす。 匏 の型は、 int型に暗黙的に倉換できる必芁がありたす。

スタック割り圓おのサむズを負にするこずはできたせん。これは、負の倀に評䟡される constant_expression ずしお項目の数を指定するコンパむル時゚ラヌです。

実行時に割り圓おられる項目の数が負の倀である堎合、動䜜は未定矩です。 0 の堎合、割り圓おは行われず、返される倀は実装定矩です。 メモリが䞍足しお項目を割り圓おられない堎合は、System.StackOverflowException ゚ラヌがスロヌされたす。

stackalloc_initializer が存圚する堎合:

  • unmanaged_typeを省略するず、stackalloc_element_initializerのセットに察しお最も䞀般的な型 (§12.6.3.17) の芏則に埓っお掚論されたす。
  • constant_expression が省略された堎合、それは stackalloc_element_initializer数であるず掚定されたす。
  • constant_expression が存圚する堎合、それは stackalloc_element_initializer数に等しくなりたす。

各 stackalloc_element_initializer は、unmanaged_type (§10.2) ぞの暗黙的な倉換を持぀必芁がありたす。 stackalloc_element_initializerは、割り圓おられたメモリ内の芁玠を、むンデックス 0 から始たる順に初期化したす。 stackalloc_initializerがない堎合、新しく割り圓おられたメモリの内容は未定矩です。

stackalloc_expressionがlocal_variable_declarationの初期化匏 (§13.6.2) ずしお盎接発生し、local_variable_typeがポむンタヌ型 (§24.3) たたは掚論 (var) である堎合、stackalloc_expressionの結果はT*型 (§24.9) のポむンタヌになりたす。 この堎合、 stackalloc_expression は安党でないコヌドに衚瀺される必芁がありたす。 それ以倖の堎合、 stackalloc_expression の結果は Span<T>型のむンスタンスになりたす。ここで、 T は unmanaged_typeです。

  • Span<T> (§C.3) は ref 構造䜓型 (§16.2.3) です。ここでは、 stackalloc_expressionによっお割り圓おられたブロックが、型指定された (T) 項目のむンデックス可胜なコレクションずしおメモリ ブロックを提瀺したす。
  • 結果の Length プロパティは、割り圓おられた項目の数を返したす。
  • 結果のむンデクサヌ (§15.9) は、割り圓おられたブロックの項目に variable_reference (§9.5) を返し、範囲がチェックされたす。

スタック割り圓お初期化子は、 catch ブロックたたは finally ブロック (§13.11) では蚱可されたせん。

泚意: stackallocを䜿甚しお割り圓おられたメモリを明瀺的に解攟する方法はありたせん。 泚釈

関数メンバヌの実行䞭に䜜成されたスタック割り圓おメモリ ブロックはすべお、その関数メンバヌが戻ったずきに自動的に砎棄されたす。

stackalloc 挔算子を陀き、C# はガベヌゞ コレクションされおいないメモリを管理するための定矩枈みのコンストラクトを提䟛したせん。 このようなサヌビスは、通垞、サポヌト クラス ラむブラリによっお提䟛されるか、基になるオペレヌティング システムから盎接むンポヌトされたす。

䟋:

// Memory uninitialized
Span<int> span1 = stackalloc int[3];
// Memory initialized
Span<int> span2 = stackalloc int[3] { -10, -15, -30 };
// Type int is inferred
Span<int> span3 = stackalloc[] { 11, 12, 13 };
// Error; result is int*, not allowed in a safe context
var span4 = stackalloc[] { 11, 12, 13 };
// Error; no conversion from Span<int> to Span<long>
Span<long> span5 = stackalloc[] { 11, 12, 13 };
// Converts 11 and 13, and returns Span<long> 
Span<long> span6 = stackalloc[] { 11, 12L, 13 };
// Converts all and returns Span<long>
Span<long> span7 = stackalloc long[] { 11, 12, 13 };
// Implicit conversion of Span<T>
ReadOnlySpan<int> span8 = stackalloc int[] { 10, 22, 30 };
// Implicit conversion of Span<T>
Widget<double> span9 = stackalloc double[] { 1.2, 5.6 };

public class Widget<T>
{
    public static implicit operator Widget<T>(Span<double> sp) { return null; }
}

span8の堎合、stackalloc は Span<int>を生成し、それが暗黙的な挔算子によっお ReadOnlySpan<int>に倉換されたす。 同様に、 span9の堎合、結果の Span<double> は、次に瀺すように、倉換を䜿甚しおナヌザヌ定矩型 Widget<double> に倉換されたす。 終了サンプル

12.8.23 nameof 挔算子

nameof_expression は、プログラム ゚ンティティの名前を定数文字列ずしお取埗するために䜿甚されたす。

nameof_expression
    : 'nameof' '(' named_entity ')'
    ;
    
named_entity
    : named_entity_target ('.' identifier type_argument_list?)*
    ;
    
named_entity_target
    : simple_name
    | 'this'
    | 'base'
    | predefined_type 
    | qualified_alias_member
    ;

nameof はキヌワヌドではないため、 nameof_expression は垞に構文的にあいたいであり、単玔な名前 nameofの呌び出しによっおあいたいになりたす。 互換性䞊の理由から、名前 の名前怜玢 (nameof) が成功した堎合、呌び出しが有効かどうかに関係なく、匏は invocation_expression ずしお扱われたす。 それ以倖の堎合は nameof_expressionです。

単玔な名前ずメンバヌ アクセスの怜玢は、コンパむル時に named_entity に察しお、 §12.8.4 および §12.8.7 で説明されおいる芏則に埓っお実行されたす。 ただし、 §12.8.4 および §12.8.7 で説明されおいる怜玢では、静的コンテキストでむンスタンス メンバヌが芋぀かったため、゚ラヌが発生したすが、 nameof_expression はそのような゚ラヌを生成したせん。

named_entity がメ゜ッド グルヌプを指定し、type_argument_listを持぀堎合、コンパむル時゚ラヌになりたす。 named_entity_target が dynamic型を持぀こずはコンパむル時゚ラヌずなりたす。

nameof_expression は string型の定数匏であり、実行時には圱響したせん。 具䜓的には、その named_entity は評䟡されず、明確な代入分析 (§9.4.4.22) では無芖されたす。 その倀は、オプションの最終 type_argument_list の前の named_entityの最埌の識別子であり、次のように倉換されたす。

  • プレフィックス "@"(䜿甚されおいる堎合) は削陀されたす。
  • 各 unicode_escape_sequence は、察応する Unicode 文字に倉換されたす。
  • すべおの formatting_characters が削陀されたす。

これらは、識別子間の等䟡性をテストするずきに、 §6.4.3 で適甚されるのず同じ倉換です。

䟋の: nameof名前空間内で宣蚀されたゞェネリック型 List<T> を想定した、さたざたな System.Collections.Generic 匏の結果を次に瀺したす。

using TestAlias = System.String;

class Program
{
    static void Main()
    {
        var point = (x: 3, y: 4);

        string n1 = nameof(System);                      // "System"
        string n2 = nameof(System.Collections.Generic);  // "Generic"
        string n3 = nameof(point);                       // "point"
        string n4 = nameof(point.x);                     // "x"
        string n5 = nameof(Program);                     // "Program"
        string n6 = nameof(System.Int32);                // "Int32"
        string n7 = nameof(TestAlias);                   // "TestAlias"
        string n8 = nameof(List<int>);                   // "List"
        string n9 = nameof(Program.InstanceMethod);      // "InstanceMethod"
        string n10 = nameof(Program.GenericMethod);      // "GenericMethod"
        string n11 = nameof(Program.NestedClass);        // "NestedClass"

        // Invalid
        // string x1 = nameof(List<>);            // Empty type argument list
        // string x2 = nameof(List<T>);           // T is not in scope
        // string x3 = nameof(GenericMethod<>);   // Empty type argument list
        // string x4 = nameof(GenericMethod<T>);  // T is not in scope
        // string x5 = nameof(int);               // Keywords not permitted
        // Type arguments not permitted for method group
        // string x6 = nameof(GenericMethod<Program>);
    }

    void InstanceMethod() { }

    void GenericMethod<T>()
    {
        string n1 = nameof(List<T>); // "List"
        string n2 = nameof(T);       // "T"
    }

    class NestedClass { }
}

この䟋の驚くべき郚分は、完党な名前空間ではなく "ゞェネリック" に nameof(System.Collections.Generic) を解決し、"String" ではなく "TestAlias" に nameof(TestAlias) するこずです。 終了サンプル

12.8.24 匿名メ゜ッド匏

anonymous_method_expression は、匿名関数を定矩する 2 ぀の方法の 1 ぀です。 これらは§ 12.22でさらに説明されおいたす。

12.8.25 コレクション匏

コレクション匏は、[]区切りのコンマ区切りの 0 個以䞊のcollection_elementセットで、1぀のコレクションを䞀緒に衚したす。

collection_expression
    : '[' (collection_element (',' collection_element)*)? ']'
    ;

collection_element
    : expression_element
    | spread_element
    ;

expression_element
    : expression
    ;

spread_element
    : '..' expression
    ;

それ自䜓では、 collection_expression には型がありたせんが、むしろタヌゲット型です。぀たり、䜿甚されるコンテキストに応じお、(§10.2.22) がタヌゲットの型に倉換されたす (このような倉換が蚱可されおいるこずを前提ずしおいたす)。 collection_initializer (§12.8.17.2.3) をサポヌトする型は、collection_expressionのタヌゲット型にするこずができたす。 CollectionBuilderAttributeで指定された型は、タヌゲット型 (§15.17.1) でもかたいたせん。

collection_elementの匏は定数である必芁はありたせん。 collection_expressionは、すべおのcollection_elementが存圚する堎合でも、コンパむル時定数ではありたせん。

䟋:

string[] colors = ["red", "white", "blue"];  // initialization
List<int> counts = [10, 25, 45, 67];
Span<double> list = [5.4, 3.9F, 123, 'x'];
ReadOnlySpan<object> items = [counts[2], 19.5, 'X', colors[1]];
int v = ((int[])[10, 20])[1];  // explicit target type cast

colorsの堎合、コレクション匏は、Length 3 を持぀string[]に倉換されたす。 countsの堎合、コレクション匏は、Count 4 のList<int>に倉換されたす。 listの堎合、コレクション匏はLength 4 のSpan<double>に倉換され、匏は必芁に応じお暗黙的に double に倉換されたす。 itemsの堎合、コレクション匏は Length 4 のReadOnlySpan<object>に倉換され、匏はボックス化されたす。 終了サンプル

collection_expression[]は空のコレクションを衚したす。 このような匏を倉換するず、コレクションのCountたたはLengthが 0 になりたす。プロパティisEmptytrueが返されたす。

spread_elementにより、匏によっお指定されたcollection_elementのセットが、そのspread_elementの堎所から新しいコレクションにコピヌされたす。 匏 は、 foreach ステヌトメントを䜿甚しお列挙可胜な゚ンティティを指定する必芁がありたす。

䟋:

string[] colors1 = ["red", "white", "blue"];
string[] colors2 = ["black", .. colors1, "yellow"];
List<string> directions = ["north", "south", "east", "west"];
Span<string> words = ["March", .. colors1, "Hello",.. directions];
ReadOnlySpan<object> things = [123, 10.5, .. directions];

int[] counts = [10, 20, 30];
List<double> values = [1.2, 3.5];
Span<ValueType> numbers = [.. counts, .. values];

colors2 には、 "black"、 "red"、 "white"、 "blue"、 "yellow"の 5 ぀の芁玠が含たれおいたす。 words は、 string 型の 2 ぀の芁玠に加えお、 string[] ず List<string>のすべおの芁玠から、瀺されおいる順序で䜜成されたす。 thingsは、int、double、およびList<string>のすべおの芁玠から䜜成されたす。 次に瀺すように、コレクションのコピヌ元のコンテナヌの型は重芁ではありたせん。 たた、 numbersの堎合、芁玠の型は同じである必芁はありたせん。 終了サンプル

spread_element内の匏が[]されおいる堎合、そのspread_elementは無芖される可胜性がありたす。芁玠は含たないためです。

12.9 単項挔算子

12.9.1 党般

+、-、! (論理吊定 §12.9.4 のみ)、~、^、++、--、キャスト、およびawait挔算子は単項挔算子ず呌ばれたす。

泚意: コンパむル時ずオヌバヌロヌドできないだけの性質のため、埌眮 null 蚱容挔算子 (§12.8.9) !は、䞊蚘の䞀芧から陀倖されたす。 泚釈

unary_expression
    : primary_expression
    | '+' unary_expression
    | '-' unary_expression
    | logical_negation_operator unary_expression
    | '~' unary_expression
    | '^' unary_expression
    | pre_increment_expression
    | pre_decrement_expression
    | cast_expression
    | await_expression
    | pointer_indirection_expression    // unsafe code support
    | addressof_expression              // unsafe code support
    ;

pointer_indirection_expression (§24.6.2) ず addressof_expression (§24.6.5) は、安党でないコヌド (§24) でのみ䜿甚できたす。

unary_expression のオペランドにコンパむル時の型 dynamicがある堎合は、動的にバむンドされたす (§12.3.3)。 この堎合、次のようになりたす。

  • unary_expressionのコンパむル時の型は次のずおりです。
    • Index ^むンデックスの from-end 挔算子 (§12.9.6) の堎合
    • dynamic 他のすべおの単項挔算子の堎合。そしお
  • 以䞋で説明する解決は、オペランドの実行時型を䜿甚しお実行時に行われたす。

12.9.2 単項プラス挔算子

フォヌム +x の挔算では、単項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。 定矩枈みの単項プラス挔算子は次のずおりです。

int operator +(int x);
uint operator +(uint x);
nint operator +(nint x);
nuint operator +(nuint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);

これらの挔算子ごずに、結果はオペランドの倀にすぎたせん。

䞊蚘で定矩された未リフトの芏定枈み単項プラス挔算子のリフト圢匏 (§12.4.8) も芏定されおいたす。

12.9.3 単項マむナス挔算子

フォヌム -x の挔算では、単項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。 定矩枈みの単項マむナス挔算子は次のずおりです。

  • 敎数吊定:

    int operator -(int x);
    nint operator -(nint x);
    long operator -(long x);
    

    結果は、0 から X を枛算するこずによっお蚈算されたす。 Xの倀がオペランド型の最小衚珟可胜な倀 (intの堎合は−2 ²¹、nintの堎合は察応する倀、たたはlongの堎合は −2⁶ ²) の堎合、Xの数孊的吊定はオペランド型内で衚されたせん。 これが checked コンテキスト内で発生した堎合は、 System.OverflowException がスロヌされたす。 unchecked コンテキスト内で発生した堎合、結果はオペランドの倀になり、オヌバヌフロヌは報告されたせん。

    吊定挔算子のオペランドが uint型の堎合は、型 longに倉換され、結果の型は longです。 䟋倖は、 int 倀 −2147483648 (−2 ²¹) を 10 進敎数リテラル (§6.4.5.3) ずしお曞き蟌むこずが蚱可される芏則です。

    吊定挔算子のオペランドが nuint型の堎合、コンパむル時゚ラヌが発生したす。

    吊定挔算子のオペランドが ulong型の堎合、コンパむル時゚ラヌが発生したす。 䟋倖は、 long 倀 −9223372036854775808 (−2 ⁶³) を 10 進敎数リテラル (§6.4.5.3) ずしお曞き蟌むこずが蚱可される芏則です。

  • 浮動小数点吊定:

    float operator -(float x);
    double operator -(double x);
    

    結果は、笊号が反転された X の倀になりたす。 x が NaN の堎合、結果も NaN です。

  • 10進数の吊定

    decimal operator -(decimal x);
    

    結果は、0 から X を枛算するこずによっお蚈算されたす。 10 進数の吊定は、 System.Decimal型の単項マむナス挔算子を䜿甚するこずず同じです。

䞊で定矩されたリフトされおいない定矩枈み単項マむナス挔算子の圢匏に加えお、リフトされた圢匏も事前に定矩されおいたす (§12.4.8)。

12.9.4 論理吊定挔算子

フォヌム !x の挔算では、単項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。 定矩枈みの論理吊定挔算子が 1 ぀だけ存圚したす。

bool operator !(bool x);

この挔算子は、オペランドの論理吊定を蚈算したす。オペランドが trueである堎合、結果は falseです。 オペランドが false の堎合、結果は true になりたす。

䞊蚘で定矩されおいるリフト解陀された事前定矩枈み論理吊定挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

泚: 接頭論理吊定挔算子ず接尟null蚱容挔算子(§12.8.9)は、同じ語圙トヌクン(!)で衚されたすが、異なるものです。 泚釈

12.9.5 ビットごずの補数挔算子

フォヌム ~x の挔算では、単項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。 定矩枈みのビットごずの補数挔算子は次のずおりです。

int operator ~(int x);
uint operator ~(uint x);
nint operator ~(nint x);
nuint operator ~(nuint x);
long operator ~(long x);
ulong operator ~(ulong x);

これらの挔算子のそれぞれに぀いお、挔算の結果は、 xのビットごずの補数です。

すべおの列挙型 E では、次のビットごずの補数挔算子が暗黙的に提䟛されたす。

E operator ~(E x);

~xを評䟡した結果 (X は基になる型 Eを持぀列挙型 U の匏) は、 (E)(~(U)x)の評䟡ずたったく同じですが、 E ぞの倉換は垞に unchecked コンテキスト (§12.8.20) のように実行されたす。

䞊蚘で定矩されおいる未リフトの定矩枈みビットごずの補数挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.9.6 Index from-end 挔算子

単項 ^ 挔算子は、 むンデックスの from-end 挔算子 (口語的には 垜子挔算子ず呌ばれたす) ず呌ばれたす。 この挔算子はオヌバヌロヌドできず (§12.4.3)、定矩枈みの挔算子が 1 ぀ありたす。

Index operator ^(int x);

フォヌム ^x の挔算の結果は、匏の結果ず等䟡な from-end Index (§18.2) 倀になりたす。

new Index(x, true)

他の unary_expressionず同様に、オペランドはコンパむル時の型 dynamic (§12.9.1) を持ち、動的にバむンドされる可胜性がありたす (§12.3.3)。 結果のコンパむル時の型は垞に Index。

むンデックスの from-end 挔算子のリフトされた (§12.4.8) 圢匏も事前に定矩されおいたす。

12.9.7 プレフィックスむンクリメント挔算子ずデクリメント挔算子

pre_increment_expression
    : '++' unary_expression
    ;

pre_decrement_expression
    : '--' unary_expression
    ;

前眮むンクリメントたたはデクリメント挔算のオペランドは、倉数、プロパティ アクセス、たたはむンデクサヌ アクセスずしお分類される匏でなければなりたせん。 挔算の結果はオペランドず同じ型の倀になりたす。

プレフィックスむンクリメントたたはデクリメント挔算のオペランドがプロパティたたはむンデクサヌアクセスである堎合、プロパティたたはむンデクサヌは、get アクセサヌず set アクセサヌたたは init アクセサヌの䞡方を持぀必芁がありたす。 そうでない堎合は、バむンド時゚ラヌが発生したす。

単項挔算子のオヌバヌロヌド解決(§12.4.4)は、特定の挔算子の実装を遞択するために適甚されたす。 定矩枈みの ++ 挔算子ず -- 挔算子は、 sbyte、 byte、 short、 ushort、 int、 uint、 nint、 nuint、 long、 ulong、 char、 floatdouble、 decimal、任意の列挙型に察しお存圚したす。 定矩枈みの ++ 挔算子は、オペランドに 1 を远加するこずによっお生成された倀を返し、定矩枈みの -- 挔算子は、オペランドから 1 を枛算するこずによっお生成された倀を返したす。 checked コンテキストでは、この加算たたは枛算の結果が結果型の範囲倖で、結果の型が敎数型たたは列挙型の堎合、 System.OverflowException がスロヌされたす。

遞択した単項挔算子の戻り倀の型から unary_expressionの型ぞの暗黙的な倉換が必芁です。それ以倖の堎合は、コンパむル時゚ラヌが発生したす。

フォヌム ++x たたは --x の前眮むンクリメントたたはデクリメント挔算の実行時凊理は、次の手順で構成されたす。

  • x が倉数ずしお分類される堎合:
    • x は、倉数を生成するために評䟡されたす。
    • x の倀は遞択された挔算子のオペランド型に倉換され、この倀を匕数ずしお挔算子が呌び出されたす。
    • 挔算子によっお返される倀は、 xの型に倉換されたす。 結果の倀は、x の評䟡によっお指定された堎所に栌玍され、操䜜の結果になりたす。
  • x がプロパティたたはむンデクサヌ アクセスずしお分類される堎合:
    • むンスタンス匏 (xがstaticされおいない堎合) ず、xに関連付けられおいる匕数リスト (xがむンデクサヌ アクセスの堎合) が評䟡され、その結果は埌続の get および set たたは init アクセサヌ呌び出しで䜿甚されたす。
    • x の get アクセサヌが呌び出されたす。
    • get アクセサヌによっお返される倀は、遞択された挔算子のオペランド型に倉換され、この倀を匕数ずしお挔算子が呌び出されたす。
    • 挔算子によっお返される倀は、 xの型に倉換されたす。 xの set アクセサヌたたは init アクセサヌは、この倀を倀匕数ずしお䜿甚しお呌び出されたす。
    • この倀は、挔算の結果にもなりたす。

++ および -- 挔算子は、ポストフィックス衚蚘 (§12.9.6) もサポヌトしおいたす。 x++ たたは x-- の結果は挔算前の x の倀ですが、 ++x たたは --x の結果は挔算埌の x の倀です。 どちらの堎合も、 x 自䜓は挔算埌に同じ倀を持ちたす。

挔算子 ++ たたは挔算子 -- 実装は、埌眮衚蚘たたはプレフィックス衚蚘を䜿甚しお呌び出すこずができたす。 2 ぀の衚蚘に察しお個別の挔算子を実装するこずはできたせん。

䞊蚘で定矩されおいるリフト解陀された定矩枈みのプレフィックス むンクリメント挔算子ずデクリメント挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.9.8 キャスト匏

匏を明瀺的に特定の型に倉換するには、 cast_expression を䜿甚したす。

cast_expression
    : '(' type ')' unary_expression
    ;

cast_expression の圢匏 (T)E においお、T は型であり、E は unary_expression に盞圓したす。これは、 の倀を明瀺的に倉換しお E の型に倉える手続きですT。 条件匏倉換 (§10.2.20) の堎合、 E から Tぞの倉換が耇数存圚する可胜性がありたす。その堎合、条件匏倉換は最埌の手段ずしおのみ䜿甚されたす。 E から Tぞの明瀺的な倉換が存圚しない堎合は、バむンド時゚ラヌが発生したす。 それ以倖の堎合、明瀺的な倉換によっお生成される倀が結果になりたす。 E が倉数を衚しおいる堎合でも、結果は垞に倀ずしお分類されたす。

cast_expression の文法は、特定の構文のあいたいさに぀ながりたす。

䟋: 匏 (x)–y は、 cast_expression (–y から型 x ぞのキャスト) ずしお解釈するこずも、 parenthesized_expression (倀 を蚈算する) ず組み合わせた x â€“ y ずしお解釈するこずもできたす。 終了サンプル

cast_expression のあいたいさを解決するために、次の芏則が存圚したす。かっこで囲たれた 1 ぀以䞊のトヌクン (§6.4) のシヌケンスは、次の少なくずも 1 ぀が該圓する堎合にのみ、 cast_expression の開始ず芋なされたす。

  • トヌクンのシヌケンスは型に察しお正しい文法ですが、匏には適しおいたせん。
  • トヌクンのシヌケンスは型の正しい文法であり、閉じかっこのすぐ埌のトヌクンはトヌクン "~"、トヌクン "!"、トヌクン "("、識別子 (§6.4.3)、リテラル (§6.4.5)、たたはキヌワヌド (§6.4.4) のいずれか (as および isを陀く) です。

䞊蚘の "正しい文法" ずいう甚語は、トヌクンのシヌケンスが特定の文法の生成に準拠する必芁があるこずを意味したす。 具䜓的には、構成識別子の実際の意味は考慮されたせん。

䟋: xずyが識別子の堎合、x.yが実際に型を衚しおいない堎合でも、x.yは型の正しい文法になりたす。 終了サンプル

泚意: 非決定芏則から、x ず y が識別子である堎合、(x)y、(x)(y)、および (x)(-y) は cast_expressionですが、たずえ (x)-y が型を識別する堎合でも、x はそうではありたせん。 ただし、x が定矩枈みの型 (intなど) を識別するキヌワヌドである堎合、その 4 ぀の圢匏はすべお キャスト匏ずされおいたすこのようなキヌワヌドを単独で匏ずしお扱うこずはできないためです。 泚釈

12.9.9 匏の埅機

12.9.9.1 党般

await 挔算子は、オペランドで衚される非同期操䜜が完了するたで、囲われた非同期関数の評䟡を䞭断するために䜿甚されたす。

await_expression
    : 'await' unary_expression
    ;

await_expressionは、非同期関数 (§15.14) の本䜓でのみ䜿甚できたす。 最も近い囲われた非同期関数内では、await_expression は、これらの堎所では発生したせん。

  • ネストされた (非同期) 匿名関数内
  • lock_statement のブロック内
  • 匿名関数を匏朚型に倉換する堎合 (§10.7.3)
  • 安党でないコンテキストの堎合

泚: await_expression は、非同期でないラムダ匏を䜿甚するように構文的に倉換されるため、query_expression内のほずんどの堎所では発生したせん。 泚釈

非同期関数内では、 await は available_identifier ずしお䜿甚されたせんが、逐語的な識別子 @await 䜿甚できたす。 したがっお、 await_expressionず識別子を含むさたざたな匏の間に構文的なあいたいさはありたせん。 非同期関数の倖郚では、 await は通垞の識別子ずしお機胜したす。

await_expression のオペランドは、タスクず呌ばれおいたす。 これは、await_expressionの評䟡時に完了する堎合ず完了しない可胜性がある非同期操䜜を衚したす。 await 挔算子の目的は、埅機䞭のタスクが完了するたで倖偎の非同期関数の実行を䞭断し、その結果を取埗するこずです。

12.9.9.2 Awaitable 匏

await_expression のタスクは、埅機可胜なである必芁がありたす。 次のいずれかが該圓する堎合、匏 t は埅機できたす。

  • t はコンパむル時の型 dynamic
  • t には、パラメヌタヌず型パラメヌタヌを持たない GetAwaiter ず呌ばれるアクセス可胜なむンスタンスたたは拡匵メ゜ッドず、次のすべおを保持する戻り倀の型 A がありたす。
    • A は、むンタヌフェむス System.Runtime.CompilerServices.INotifyCompletion を実装したす (以䞋、簡朔にするために INotifyCompletion ず呌ばれたす)。
    • A には、タむプ IsCompleted の、アクセス可胜で読み取り可胜なむンスタンスプロパティ bool がある。
    • A には、パラメヌタヌも型パラメヌタヌも含たない、アクセス可胜なむンスタンス メ゜ッド GetResult がありたす

GetAwaiter メ゜ッドの目的は、タスクの awaiter を取埗するこずです。 型 A は、await 匏で、awaiter 型ず呌ばれたす。

IsCompleted プロパティの目的は、タスクが既に完了しおいるかどうかを刀断するこずです。 その堎合、評䟡を䞭断する必芁はありたせん。

INotifyCompletion.OnCompleted メ゜ッドの目的は、タスクが完了するず呌び出される「継続」のデリゲヌトSystem.Action型をタスクに登録するこずです。

GetResult メ゜ッドの目的は、完了したタスクの結果を取埗するこずです。 この結果は、正垞に完了し結果倀を持぀堎合もあれば、GetResult メ゜ッドによっおスロヌされる䟋倖である堎合もありたす。

12.9.9.3 await 匏の分類

匏 await t は、匏 (t).GetAwaiter().GetResult()ず同じように分類されたす。 したがっお、 GetResult の戻り倀の型が void堎合、 await_expression は䜕も分類されたせん。 void 以倖の戻り倀の型 Tがある堎合、 await_expression は T型の倀ずしお分類されたす。

12.9.9.4 await 匏の実行時評䟡

実行時に、匏 await t は次のように評䟡されたす。

  • awaiter a は、匏 (t).GetAwaiter()を評䟡するこずによっお取埗されたす。
  • bool b は、匏 (a).IsCompletedを評䟡するこずによっお埗られたす。
  • b が false 堎合、評䟡は、むンタヌフェむス a を実装 System.Runtime.CompilerServices.ICriticalNotifyCompletion かどうかによっお異なりたす (以䞋、簡朔にするために ICriticalNotifyCompletion ず呌ばれたす)。 このチェックはバむンド時に行われたす。぀たり、 a がコンパむル時の型 dynamicを持぀堎合は実行時、それ以倖の堎合はコンパむル時です。 再開デリゲヌト r 瀺したす (§15.14):
    • a が ICriticalNotifyCompletionを実装しおいない堎合は、匏 ((a) as INotifyCompletion).OnCompleted(r) が評䟡されたす。
    • a が ICriticalNotifyCompletionを実装しおいる堎合は、匏 ((a) as ICriticalNotifyCompletion).UnsafeOnCompleted(r) が評䟡されたす。
    • 評䟡が䞭断され、非同期関数の珟圚の呌び出し元に制埡が返されたす。
  • 盎埌 (b が trueされた堎合) たたは再開デリゲヌトの埌の呌び出し時 (b が falseされた堎合)、匏 (a).GetResult() が評䟡されたす。 倀を返す堎合、その倀は await_expressionの結果になりたす。 それ以倖の堎合、結果はありたせん。

INotifyCompletion.OnCompleted および ICriticalNotifyCompletion.UnsafeOnCompleted むンタヌフェむス メ゜ッドの awaiter の実装により、デリゲヌト r が最倧 1 回呌び出されたす。 それ以倖の堎合、包含する非同期関数の動䜜は未定矩です。

12.10 匏あり

with_expressionでは、既存のレコヌド クラス、レコヌド構造䜓、たたはレコヌド以倖の構造䜓むンスタンスのコピヌである新しいレコヌド クラス、レコヌド構造䜓、たたはレコヌド以倖の構造䜓むンスタンスを䜜成するこずで、非砎壊的な倉曎を行えたす。必芁に応じお、指定したプロパティずフィヌルドを倉曎したす。

with_expression
    : switch_expression
    | switch_expression 'with' '{' member_initializer_list? '}'
    ;

with_expressionはステヌトメントずしお䜿甚できたせん。

受信偎の型は、void 以倖のレコヌド クラス、レコヌド構造䜓、たたはレコヌド以倖の構造䜓型である必芁がありたす。

識別子 は、受信者の型のアクセス可胜なむンスタンス フィヌルドたたはプロパティである必芁がありたす。

倉曎されるすべおの䜍眮指定プロパティは、set アクセサヌず init アクセサヌの䞡方を持぀必芁がありたす。

この匏は次のように評䟡されたす。

  • レコヌド クラス型の堎合、受信偎のクロヌン メ゜ッド (§15.16.4.4) が呌び出され、その結果が受信偎の型に倉換されたす。
  • レコヌド構造䜓たたは非レコヌド構造䜓型の堎合、受信偎がコピヌされたす。
  • 各 member_initializer は、倉換の結果のフィヌルドたたはプロパティ アクセスぞの割り圓おず同じ方法で凊理されたす。 割り圓おは字句の順序で凊理されたす。 member_initializer_listを省略するず、メンバヌは倉曎されたせん。

䟋:

Person person1 = new("Mary", "Smith") { Age = 35 };    // create an immutable record
Person person2 = person1 with { FirstName = "Jane" };  // copy with FirstName changed
person2 = person1 with { Age = 40 };                   // copy with Age changed
person2 = person1 with { };                            // copy with no changes

public record Person(string FirstName, string LastName)
{
    public int Age { get; init; }
}

終了サンプル

12.11 Range 挔算子

..挔算子は範囲挔算子ず呌ばれたす。

range_expression
    : unary_expression
    | unary_expression? '..' unary_expression?
    ;

定矩枈みの範囲挔算子は次のずおりです。

Range operator ..(Index x, Index y);

範囲挔算子はオヌバヌロヌドできたせん (§12.4.3)。

すべおの範囲匏は、次のような圢匏 x..yを持぀ものずしお扱われたす。

  • x は巊オペランド (存圚する堎合) です。それ以倖の堎合は匏 0。
  • y は、存圚する堎合は右オペランド、それ以倖の堎合は匏 ^0。

操䜜の結果は、匏の結果ず同等の Range (§18.3) 倀になりたす。

new Range(x, y)

範囲匏のどちらか䞀方たたは䞡方のオペランドにコンパむル時の型が dynamic堎合、匏は動的にバむンドされたす (§12.3.3)。 結果のコンパむル時の型は垞に Range。

範囲挔算子のリフト (§12.4.8) 圢匏も事前に定矩されおいたす。

範囲挔算子は非連想 (§12.4.2) です。

12.12 Switch 匏

switch_expressionは、匏コンテキストでswitchのようなセマンティクスを提䟛したす。

switch_expression
    : range_expression
    | switch_expression 'switch' '{' switch_expression_arms? '}'
    ;

switch_expression_arms
    : switch_expression_arm (',' switch_expression_arm)* ','?
    ;

switch_expression_arm
    : pattern case_guard? '=>' switch_expression_arm_expression
    ;

switch_expression_arm_expression
    : expression
    ;

switch_expressionの型は、switch_expression_armのswitch_expression_arm_expressionの最も䞀般的な型 §12.6.3.17) です (そのような型が存圚する堎合、および各switch_expression_arm_expressionがその型に暗黙的に倉換できる堎合)。 それ以倖の堎合、 switch_expression には型はありたせんが、 匏の倉換を切り替える 可胜性がありたす (§10.2.18)。

いずれかのswitch_expression_armのパタヌンが、スむッチ匏の前の非ガヌド (§13.8.3) のパタヌンセット (§13.8.3) によっおサブスムswitch_expression_arm堎合、゚ラヌになりたす。

スむッチ匏は、入力のすべおの倀がスむッチ匏の少なくずも 1 ぀のアヌムによっお凊理される堎合、 網矅的 です。 スむッチ匏が完党でない堎合は、譊告が発行される可胜性がありたす。

実行時に、switch_expressionの結果は、switch_expressionの巊偎の匏がswitch_expression_armのパタヌンず䞀臎し、switch_expression_armのcase_guard (存圚する堎合) がに評䟡される最初のtrueの匏の倀です。 このような switch_expression_armがない堎合、 switch_expression は䟋倖 System.Runtime.CompilerServices.SwitchExpressionExceptionのむンスタンスをスロヌしたす。

泚: 䞊蚘の芁点は、switch_expression_armsを持たないswitch_expressionはコンパむル時の譊告を生成し、実行時に評䟡された堎合は垞に䟋倖をスロヌするこずです。 泚釈

䟋: 次は、オンラむン マップ䞊の芖芚的な方向を衚す列挙型の倀を、察応するカヌディナ方向に倉換したす。

static Orientation ToOrientation(Direction direction) => direction switch
{
    Direction.Up    => Orientation.North,
    Direction.Right => Orientation.East,
    Direction.Down  => Orientation.South,
    Direction.Left  => Orientation.West,
    _ => throw new ArgumentOutOfRangeException(direction.ToString()),
};

public enum Direction
{
    Up,
    Down,
    Right,
    Left
}

public enum Orientation
{
    North,
    South,
    East,
    West
}

終了サンプル

12.13 算術挔算子

12.13.1 党般

*、 /、 %、 +、および - 挔算子は算術挔算子ず呌ばれたす。

multiplicative_expression
    : switch_expression
    | multiplicative_expression '*' switch_expression
    | multiplicative_expression '/' switch_expression
    | multiplicative_expression '%' switch_expression
    ;

additive_expression
    : multiplicative_expression
    | additive_expression '+' multiplicative_expression
    | additive_expression '-' multiplicative_expression
    ;

算術挔算子のオペランドにコンパむル時の型 dynamicがある堎合、匏は動的にバむンドされたす (§12.3.3)。 この堎合、匏のコンパむル時の型は dynamicであり、コンパむル時の型 dynamicを持぀オペランドの実行時の型を䜿甚しお、実行時に以䞋で説明する解決が行われたす。

12.13.2 乗算挔算子

フォヌム x * y の挔算では、二項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの乗算挔算子を次に瀺したす。 挔算子はすべお、 x ず y の積を蚈算したす。

  • 敎数乗算:

    int operator *(int x, int y);
    uint operator *(uint x, uint y);
    nint operator *(nint x, nint y);
    nuint operator *(nuint x, nuint y);
    long operator *(long x, long y);
    ulong operator *(ulong x, ulong y);
    

    checked コンテキストでは、生成物が結果型の範囲倖にある堎合、System.OverflowException がスロヌされたす。 unchecked コンテキストでは、オヌバヌフロヌは報告されず、結果の皮類の範囲倖の重芁な䞊䜍ビットは砎棄されたす。

  • 浮動小数点乗算:

    float operator *(float x, float y);
    double operator *(double x, double y);
    

    積は IEC 60559 算術の芏則に埓っお蚈算されたす。 次の衚に、0 以倖の有限倀、れロ、無限倧、および NaN のすべおの可胜な組み合わせの結果を瀺したす。 この衚では、x ず y は正の有限倀です。 z は、最も近い衚珟可胜な倀に䞞められた x * yの結果です。 結果の倧きさが倉換先の型に察しお倧きすぎる堎合、 z は無限倧です。 䞞めのために、 z も x もれロでなくおも、 y は 0 になる可胜性がありたす。

    +y -y +0 -0 +∞ -∞ NaN
    +x +z -z +0 -0 +∞ -∞ NaN
    -x -z +z -0 +0 -∞ +∞ NaN
    +0 +0 -0 +0 -0 NaN NaN NaN
    -0 -0 +0 -0 +0 NaN NaN NaN
    +∞ +∞ -∞ NaN NaN +∞ -∞ NaN
    -∞ -∞ +∞ NaN NaN -∞ +∞ NaN
    NaN NaN NaN NaN NaN NaN NaN NaN

    (特に明蚘されおいない堎合を陀き、 §12.13.2–§12.13.6 の浮動小数点テヌブルでは、"+" の䜿甚は倀が正であるこずを意味したす。"-" は倀が負であるこずを意味し、笊号がない堎合は、倀が正たたは負であるか、笊号がない可胜性があるこずを意味したす (NaN)。

  • 小数の乗算

    decimal operator *(decimal x, decimal y);
    

    結果の倀の倧きさが10進圢匏で衚珟するには倧きすぎる堎合、System.OverflowExceptionがスロヌされたす。 䞞めのため、どちらのオペランドも 0 でない堎合でも、結果は 0 になる可胜性がありたす。 四捚五入前の結果のスケヌルは、2 ぀のオペランドのスケヌルの合蚈になりたす。 10 進数乗算は、 System.Decimal型の乗算挔算子を䜿甚するこずず同じです。

䞊で定矩されたリフトされおいない定矩枈み乗算挔算子のリフトされた圢匏 (§12.4.8) も事前に定矩されおいたす。

12.13.3 陀算挔算子

フォヌム x / y の挔算では、二項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの陀算挔算子を次に瀺したす。 挔算子はどれも、x ず yの商を蚈算したす。

  • 敎数の陀算:

    int operator /(int x, int y);
    uint operator /(uint x, uint y);
    nint operator /(nint x, nint y);
    nuint operator /(nuint x, nuint y);
    long operator /(long x, long y);
    ulong operator /(ulong x, ulong y);
    

    右オペランドの倀が 0 の堎合、System.DivideByZeroException がスロヌされたす。

    陀算は結果を 0 に䞞めたす。 したがっお、結果の絶察倀は、2 ぀のオペランドの商の絶察倀以䞋の最倧の敎数になりたす。 2 ぀のオペランドが同じ笊号を持ち、2 ぀のオペランドが反察の笊号を持぀堎合、0 たたは負の堎合、結果は 0 たたは正になりたす。

    巊オペランドが衚珟可胜な最小の int、 nint、たたは long 倀であり、右オペランドが –1堎合、オヌバヌフロヌが発生したす。 checked コンテキストでは、System.ArithmeticException (たたはそのサブクラス) がスロヌされる原因になりたす。 unchecked コンテキストでは、System.ArithmeticException (たたはそのサブクラス) がスロヌされるか、オヌバヌフロヌが巊オペランドの結果の倀ず共にレポヌトされないかどうかに぀いお実装定矩されたす。

  • 浮動小数点の陀算:

    float operator /(float x, float y);
    double operator /(double x, double y);
    

    商は IEC 60559 算術の芏則に埓っお蚈算されたす。 次の衚に、0 以倖の有限倀、れロ、無限倧、および NaN のすべおの可胜な組み合わせの結果を瀺したす。 この衚では、x ず y は正の有限倀です。 z は、最も近い衚珟可胜な倀に䞞められた x / yの結果です。

    +y -y +0 -0 +∞ -∞ NaN
    +x +z -z +∞ -∞ +0 -0 NaN
    -x -z +z -∞ +∞ -0 +0 NaN
    +0 +0 -0 NaN NaN +0 -0 NaN
    -0 -0 +0 NaN NaN -0 +0 NaN
    +∞ +∞ -∞ +∞ -∞ NaN NaN NaN
    -∞ -∞ +∞ -∞ +∞ NaN NaN NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • 10 進法の陀算:

    decimal operator /(decimal x, decimal y);
    

    右オペランドの倀が 0 の堎合、System.DivideByZeroException がスロヌされたす。 結果の倀の倧きさが10進圢匏で衚珟するには倧きすぎる堎合、System.OverflowExceptionがスロヌされたす。 䞞めのため、最初のオペランドが 0 でない堎合でも、結果は 0 になる可胜性がありたす。 䞞める前の結果のスケヌルは、正確な結果ず同じ結果を保持する優先スケヌルに最も近いスケヌルです。 掚奚されるスケヌルは、x のスケヌルから yのスケヌルを匕いたものです。

    10 進数陀算は、 System.Decimal型の陀算挔算子を䜿甚するこずず同じです。

䞊蚘で定矩されおいる未リフトの定矩枈み陀算挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.13.4 剰䜙挔算子

フォヌム x % y の挔算では、二項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの剰䜙挔算子を次に瀺したす。 挔算子はすべお、 x ず y の間の陀算の剰䜙を蚈算したす。

  • 敎数の剰䜙:

    int operator %(int x, int y);
    uint operator %(uint x, uint y);
    nint operator %(nint x, nint y);
    nuint operator %(nuint x, nuint y);
    long operator %(long x, long y);
    ulong operator %(ulong x, ulong y);
    

    x % y の結果は、 x â€“ (x / y) * yによっお生成される倀です。 y が 0 である堎合は、System.DivideByZeroException がスロヌされたす。

    巊オペランドが最小のint、nint、たたはlong倀で、右オペランドが–1堎合、System.OverflowExceptionが䟋倖をスロヌする堎合にのみ、x / yがスロヌされたす。

  • 浮動小数点の剰䜙:

    float operator %(float x, float y);
    double operator %(double x, double y);
    

    次の衚に、0 以倖の有限倀、れロ、無限倧、および NaN のすべおの可胜な組み合わせの結果を瀺したす。 この衚では、x ず y は正の有限倀です。 z は x % y の結果であり、 x â€“ n * yずしお蚈算されたす。ここで、n は x / y以䞋の最倧の敎数です。 剰䜙を蚈算するこの方法は、敎数オペランドに䜿甚される方法に䌌おいたすが、IEC 60559 定矩 (n は x / yに最も近い敎数) ずは異なりたす。

    +y -y +0 -0 +∞ -∞ NaN
    +x +z +z NaN NaN +x +x NaN
    -x -z -z NaN NaN -x -x NaN
    +0 +0 +0 NaN NaN +0 +0 NaN
    -0 -0 -0 NaN NaN -0 -0 NaN
    +∞ NaN NaN NaN NaN NaN NaN NaN
    -∞ NaN NaN NaN NaN NaN NaN NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • 10 進法の剰䜙:

    decimal operator %(decimal x, decimal y);
    

    右オペランドの倀が 0 の堎合、System.DivideByZeroException がスロヌされたす。 System.ArithmeticException (たたはそのサブクラス) がスロヌされる条件は、実装によっお定矩されたす。 準拠する実装が、x % y の䟋倖をスロヌしなくおも、x / y は䟋倖をスロヌしたせん。 䞞める前の結果のスケヌルは、2 ぀のオペランドのスケヌルの倧きい方であり、0 以倖の堎合、結果の笊号は xのスケヌルず同じです。

    10 進剰䜙は、 System.Decimal型の剰䜙挔算子を䜿甚するこずず同じです。

    泚意: これらの芏則により、すべおの型に察しお、結果が巊オペランドの反察の笊号を持぀こずはありたせん。 泚釈

䞊で定矩された未リフト状態の定矩枈み剰䜙挔算子のリフト圢匏§12.4.8もあらかじめ定矩されおいたす。

12.13.5 加算挔算子

フォヌム x + y の挔算では、二項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの加算挔算子を次に瀺したす。 数倀型ず列挙型の堎合、定矩枈みの加算挔算子は、2 ぀のオペランドの合蚈を蚈算したす。 䞀方たたは䞡方のオペランドが string型の堎合、定矩枈みの加算挔算子はオペランドの文字列衚珟を連結したす。 䞡方のオペランドが ReadOnlySpan<byte> 型で、䞡方がセマンティック UTF-8 バむト衚珟である堎合、定矩枈みの加算挔算子はオペランドのバむトを連結したす。

  • 敎数の加算:

    int operator +(int x, int y);
    uint operator +(uint x, uint y);
    nint operator +(nint x, nint y);
    nuint operator +(nuint x, nuint y);
    long operator +(long x, long y);
    ulong operator +(ulong x, ulong y);
    

    checked コンテキストでは、合蚈が結果型の範囲倖である堎合、System.OverflowExceptionがスロヌされたす。 unchecked コンテキストでは、オヌバヌフロヌは報告されず、結果の皮類の範囲倖の重芁な䞊䜍ビットは砎棄されたす。

  • 浮動小数点加算:

    float operator +(float x, float y);
    double operator +(double x, double y);
    

    和は IEC 60559 算術の芏則に埓っお蚈算されたす。 次の衚に、0 以倖の有限倀、れロ、無限倧、および NaN のすべおの可胜な組み合わせの結果を瀺したす。 この衚では、x ず y は 0 以倖の有限倀であり、z は x + y の結果です。 x ず y が同じ倧きさで笊号が逆の堎合、z は正のれロになりたす。 x + y が倧きすぎお倉換先の型で衚すには、 z は x + yず同じ笊号を持぀無限倧です。

    y +0 -0 +∞ -∞ NaN
    x z x x +∞ -∞ NaN
    +0 y +0 +0 +∞ –∞ NaN
    -0 y +0 -0 +∞ -∞ NaN
    +∞ +∞ +∞ +∞ +∞ NaN NaN
    -∞ -∞ -∞ -∞ NaN -∞ NaN
    NaN NaN NaN NaN NaN NaN NaN
  • 10 進法の加算:

    decimal operator +(decimal x, decimal y);
    

    結果の倀の倧きさが10進圢匏で衚珟するには倧きすぎる堎合、System.OverflowExceptionがスロヌされたす。 䞞める前の結果のスケヌルは、2 ぀のオペランドのスケヌルのうち倧きい方です。

    10 進加算は、 System.Decimal型の加算挔算子を䜿甚するこずず同じです。

  • 列挙の加算。 すべおの列挙型は、次の定矩枈みの挔算子を暗黙的に提䟛したす。ここで、 E は列挙型、 U は Eの基になる型です。

    E operator +(E x, U y);
    E operator +(U x, E y);
    

    実行時に、これらの挔算子は (E)((U)x + (U)y) ずたったく同じように評䟡されたす。

  • UTF-16 文字列連結:

    string operator +(string x, string y);
    string operator +(string x, object y);
    string operator +(object x, string y);
    

    バむナリ + 挔算子のこれらのオヌバヌロヌドは、UTF-16 文字列の連結を実行したす。 オペランドが null堎合は、空の UTF-16 文字列が眮き換えられたす。 それ以倖の堎合、ref 構造䜓 (string) ではない以倖のオペランドは、ToString型から継承された仮想object メ゜ッドを呌び出すこずによっお、UTF-16 文字列衚珟に倉換されたす。 ToStringがnullを返す堎合、空の UTF-16 文字列が眮換されたす。

    䟋:

    class Test
    {
        static void Main()
        {
            string s = null;
            Console.WriteLine("s = >" + s + "<");  // Displays s = ><
    
            int i = 1;
            Console.WriteLine("i = " + i);         // Displays i = 1
    
            float f = 1.2300E+15F;
            Console.WriteLine("f = " + f);         // Displays f = 1.23E+15
    
            decimal d = 2.900m;
            Console.WriteLine("d = " + d);         // Displays d = 2.900
       }
    }
    

    コメントに衚瀺される出力は、US-English システムでの䞀般的な結果です。 正確な出力は、実行環境のリヌゞョン蚭定によっお異なりたす。 文字列連結挔算子自䜓はいずれの堎合も同じように動䜜したすが、実行䞭に暗黙的に呌び出される ToString メ゜ッドは、地域蚭定の圱響を受ける可胜性がありたす。

    終了サンプル

    挔算子の結果は、巊オペランドの文字の埌に右オペランドの文字が続く string です。 文字列連結挔算子は、 null 倀を返したせん。 メモリ䞍足で結果の文字列を割り圓おられない堎合、System.OutOfMemoryException が投げられる可胜性がありたす。

  • UTF-8 文字列連結:

    ReadOnlySpan<byte> operator +(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y);
    

    バむナリ + 挔算子のこのオヌバヌロヌドは、UTF-8 文字列リテラルず、この挔算子の他のアプリケヌションの結果の連結を実行したす (これは UTF-16 文字列連結よりもはるかに制限が厳しくなっおいたす)。 䞡方のオペランドが セマンティック UTF-8 バむト衚珟である堎合にのみ適甚されたす。 オペランドは、 UTF-8 文字列リテラル、この挔算子の適甚結果、たたは囲たれた匏が意味的に UTF-8 バむト衚珟であるかっこで囲たれた匏である堎合、 意味的には UTF-8 バむト衚珟です。

    挔算子の結果は、巊オペランドのバむトず右オペランドのバむトで構成される ReadOnlySpan<byte> です。 結果自䜓は 意味的には UTF-8 バむト衚珟であるため、この挔算子をさらに適甚するためのオペランドずしお䜿甚できたす。

    䟋:

    ReadOnlySpan<byte> sp1 = "ABC"u8 + "DEF"u8;             // OK
    ReadOnlySpan<byte> sp2 = sp1 + "DEF"u8;                 // error
    ReadOnlySpan<byte> sp3 = "ABC"u8 + "DEF"u8 + "123"u8;   // OK
    ReadOnlySpan<byte> sp4 = "ABC"u8 + (ReadOnlySpan<byte>)stackalloc byte[]
      { (byte)'D', (byte)'E', (byte)'F', (byte)'\x0' };     // error
    

    sp1の堎合、䞡方のオペランドは UTF-8 文字列リテラルです。 ただし、 sp1 初期化されるず、その UTF-8 血統は远跡されなくなりたす。 ぀たり、 sp1 自䜓は UTF-8 で゚ンコヌドされおいるずは芋なされたせん。 そのため、 sp2の初期化の堎合はオペランドにするこずはできたせん。 sp3の初期化子では、オペランドの巊偎のペアが評䟡され、䞡方が UTF-8 文字列リテラルであるため、結果も UTF-8 ゚ンコヌドず芋なされるため、右偎の挔算子の巊オペランドずしおさらに䜿甚できたす。 sp4の堎合、䞡方のオペランドがReadOnlySpan<byte>されおいる間、Span<byte>によっお返されるstackallocが UTF-8 文字列リテラル (぀たり、null バむト タヌミネヌタを持぀バむト配列) の内郚圢匏を持っおいる堎合でも、巊偎のオペランドのみが UTF-8 ゚ンコヌドされたす。 §6.4.5.6 を参照しおください。 終了サンプル

  • デリゲヌトの組み合わせ。 すべおのデリゲヌト型は、次の定矩枈みの挔算子を暗黙的に提䟛したす。ここで、 D はデリゲヌト型です。

    D operator +(D x, D y);
    

    最初のオペランドが null の堎合、挔算の結果は 2 番目のオペランドの倀になりたす (それが nullである堎合でも)。 それ以倖の堎合、2 番目のオペランドが null堎合、挔算の結果は最初のオペランドの倀になりたす。 それ以倖の堎合、挔算の結果は、呌び出しリストが最初のオペランドの呌び出しリスト内の芁玠で構成され、その埌に 2 番目のオペランドの呌び出しリスト内の芁玠が続く新しいデリゲヌト むンスタンスになりたす。 ぀たり、結果のデリゲヌトの呌び出しリストは、2 ぀のオペランドの呌び出しリストを連結したものです。

    泚: デリゲヌトの組み合わせの䟋に぀いおは、 §12.13.6 および §21.6 を参照しおください。 System.Delegate はデリゲヌト型ではないため、挔算子 + はそれに察しお定矩されおいたせん。泚蚘

䞊で定矩した、リフトされおいない定矩枈み加算挔算子のリフトされた圢匏 (§12.4.8) も定矩枈みです。

12.13.6 枛算挔算子

フォヌム x â€“ y の挔算では、二項挔算子のオヌバヌロヌド解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの枛算挔算子を以䞋に瀺したす。 挔算子はすべお、 yから x を枛算したす。

  • 敎数の枛算:

    int operator -(int x, int y);
    uint operator -(uint x, uint y);
    nint operator -(nint x, nint y);
    nuint operator -(nuint x, nuint y);
    long operator -(long x, long y);
    ulong operator -(ulong x, ulong y);
    

    checked コンテキストでは、差異が結果型の範囲倖にある堎合、System.OverflowException がスロヌされたす。 unchecked コンテキストでは、オヌバヌフロヌは報告されず、結果の皮類の範囲倖の重芁な䞊䜍ビットは砎棄されたす。

  • 浮動小数点枛算:

    float operator -(float x, float y);
    double operator -(double x, double y);
    

    差は IEC 60559 算術の芏則に埓っお蚈算されたす。 次の衚に、0 以倖の有限倀、れロ、無限倧、および NaN のすべおの可胜な組み合わせの結果を瀺したす。 この衚では、x ず y は 0 以倖の有限倀であり、z は x â€“ y の結果です。 x ず y が等しい堎合、z は正のれロになりたす。 x â€“ y が倧きすぎお倉換先の型で衚すには、 z は x â€“ yず同じ笊号を持぀無限倧です。

    y +0 -0 +∞ -∞ NaN
    x z x x -∞ +∞ NaN
    +0 -y +0 +0 -∞ +∞ NaN
    -0 -y -0 +0 -∞ +∞ NaN
    +∞ +∞ +∞ +∞ NaN +∞ NaN
    -∞ -∞ -∞ -∞ -∞ NaN NaN
    NaN NaN NaN NaN NaN NaN NaN

    (䞊蚘の衚では、 -y の゚ントリは の y を衚しおおり、倀が負であるずいう意味ではありたせん。)

  • 10 進法の枛算:

    decimal operator -(decimal x, decimal y);
    

    結果の倀の倧きさが10進圢匏で衚珟するには倧きすぎる堎合、System.OverflowExceptionがスロヌされたす。 䞞める前の結果のスケヌルは、2 ぀のオペランドのスケヌルのうち倧きい方です。

    10 進枛算は、 System.Decimal型の枛算挔算子を䜿甚するこずず同じです。

  • 列挙の枛算。 すべおの列挙型は、次の定矩枈みの挔算子を暗黙的に提䟛したす。ここで、 E は列挙型、 U は Eの基になる型です。

    U operator -(E x, E y);
    

    この挔算子は、 (U)((U)x â€“ (U)y)ずたったく同じように評䟡されたす。 ぀たり、挔算子は、 x ず yの序数倀の差を蚈算し、結果の型は列挙型の基になる型になりたす。

    E operator -(E x, U y);
    

    この挔算子は、 (E)((U)x â€“ y)ずたったく同じように評䟡されたす。 蚀い換えるず、挔算子は列挙型の基になる型から倀を枛算し、列挙型の倀を生成したす。

  • デリゲヌトの削陀。 すべおのデリゲヌト型は、次の定矩枈みの挔算子を暗黙的に提䟛したす。ここで、 D はデリゲヌト型です。

    D operator -(D x, D y);
    

    そのセマンティクスを次に瀺したす。

    • 最初のオペランドが null の堎合は、挔算結果は null になりたす。
    • それ以倖の堎合、2 番目のオペランドが null堎合、挔算の結果は最初のオペランドの倀になりたす。
    • それ以倖の堎合、䞡方のオペランドは空でない呌び出しリスト (§21.2) を衚したす。
      • デリゲヌト等倀挔算子 (§12.15.9) によっお決定されたリストが等しい堎合、操䜜の結果は null。
      • それ以倖の堎合、2 番目のオペランドのリストが最初のオペランドのサブリストである堎合、挔算の結果は、2 番目のオペランドの゚ントリが削陀された最初のオペランドのリストで構成される新しい呌び出しリストになりたす。 (サブリストの等䟡性を刀断するために、察応する゚ントリはデリゲヌト等倀挔算子ず比范されたす)。2 番目のオペランドのリストが、最初のオペランドのリスト内の連続する゚ントリの耇数のサブリストず䞀臎する堎合、連続する゚ントリの最埌に䞀臎するサブリストが削陀されたす。
      • それ以倖の堎合、挔算の結果は巊オペランドの倀になりたす。

    オペランドのリストもしあればは、どちらも凊理の過皋で倉曎されたせん。

    䟋:

    delegate void D(int x);
    
    class C
    {
        public static void M1(int i) { ... }
        public static void M2(int i) { ... }
    }
    
    class Test
    {
        static void Main()
        {
            D cd1 = new D(C.M1);
            D cd2 = new D(C.M2);
            D list = null;
    
            list = null - cd1;                             // null
            list = (cd1 + cd2 + cd2 + cd1) - null;         // M1 + M2 + M2 + M1
            list = (cd1 + cd2 + cd2 + cd1) - cd1;          // M1 + M2 + M2
            list = (cd1 + cd2 + cd2 + cd1) - (cd1 + cd2);  // M2 + M1
            list = (cd1 + cd2 + cd2 + cd1) - (cd2 + cd2);  // M1 + M1
            list = (cd1 + cd2 + cd2 + cd1) - (cd2 + cd1);  // M1 + M2
            list = (cd1 + cd2 + cd2 + cd1) - (cd1 + cd1);  // M1 + M2 + M2 + M1
            list = (cd1 + cd2 + cd2 + cd1) - (cd1 + cd2 + cd2 + cd1);  // null
        }
    }
    

    終了サンプル

䞊蚘で定矩されおいる未リフトの定矩枈み枛算挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.14 シフト挔算子

<<、>>、および>>>挔算子は、ビットシフト挔算を実行するために䜿甚されたす。

shift_expression
    : additive_expression
    | shift_expression '<<' additive_expression
    | shift_expression right_shift additive_expression
    | shift_expression unsigned_right_shift additive_expression
    ;

shift_expression のオペランドにコンパむル時の型 dynamic がある堎合、匏は動的にバむンドされたす (§12.3.3)。 この堎合、匏のコンパむル時の型は dynamicであり、コンパむル時の型 dynamicを持぀オペランドの実行時の型を䜿甚しお、実行時に以䞋で説明する解決が行われたす。

動的バむンディングでは、 enum System.Linq.Expressions.ExpressionType 型の倀を䜿甚しお、バむナリ挔算子の皮類をランタむム バむンダヌに通信したす。 笊号なし右シフト挔算子を具䜓的に衚す列挙型メンバヌがないため、 >>> の動的バむンディングはサポヌトされおいたせん。

フォヌム x << count、 x >> count、たたは x >>> countの操䜜では、2 項挔算子のオヌバヌロヌド解決 (§12.4.5) を適甚しお、特定の挔算子の実装を遞択したす。 巊偎のオペランドは型 Tに倉換されたす。ここで、 T は、オペランドの䜿甚可胜なすべおの倀を完党に衚すこずができる int、 uint、 long、および ulong の最初の倀です。 その埌、 T型の有効桁数を䜿甚しお操䜜が実行され、結果の型が Tされたす。

オヌバヌロヌドされたシフト挔算子を宣蚀する堎合、最初のオペランドの型は、垞に挔算子宣蚀を含むクラスたたは構造䜓になりたす。

unsigned_right_shift挔算子 (>>>) は、匏ツリヌには存圚したせん。

泚: 笊号付き型に察する定矩枈みの >>> 挔算子のセマンティクスは、笊号なし型に倉換を远加せずに正確に衚すこずはできたせん。 泚釈

定矩枈みのシフト挔算子を次に瀺したす。

  • 巊シフト:

    int operator <<(int x, int count);
    uint operator <<(uint x, int count);
    nint operator <<(nint x, int count);
    nuint operator <<(nuint x, int count);
    long operator <<(long x, int count);
    ulong operator <<(ulong x, int count);
    

    この<<挔算子xは、以䞋のように蚈算されたビット数だけ巊にシフトしたす。

    結果の型 x の範囲倖の䞊䜍ビットは砎棄され、残りのビットは巊にシフトされ、䞋䜍の空きビット䜍眮はれロに蚭定されたす。

  • 右シフト:

    int operator >>(int x, int count);
    uint operator >>(uint x, int count);
    nint operator >>(nint x, int count);
    nuint operator >>(nuint x, int count);
    long operator >>(long x, int count);
    ulong operator >>(ulong x, int count);
    int operator >>>(int x, int count);
    uint operator >>>(uint x, int count);
    nint operator >>>(nint x, int count);
    nuint operator >>>(nuint x, int count);
    long operator >>>(long x, int count);
    ulong operator >>>(ulong x, int count);
    

    >> 挔算子は、䞋蚘に説明するように蚈算されたビット数分だけ、x を右にシフトしたす。

    xがint、nint、たたはlongの型である堎合、xの䞋䜍ビットは砎棄され、残りのビットは右にシフトされ、xが負でない堎合は䞊䜍の空のビット䜍眮が 0 に蚭定され、xが負の堎合は 1 に蚭定されたす。

    xがuint、nuint、たたはulongの型である堎合、xの䞋䜍ビットは砎棄され、残りのビットは右にシフトされ、䞊䜍の空のビット䜍眮は 0 に蚭定されたす。

    >>>挔算子は、次のように蚈算されたビット数だけ右xシフトしたす。xの䞋䜍ビットは砎棄され、残りのビットは右にシフトされ、䞊䜍の空のビット䜍眮は 0 に蚭定されたす。

定矩枈みの挔算子の堎合、シフトするビット数は次のように蚈算されたす。

  • x の型が int たたは uintの堎合、シフト カりントは count の䞋䜍 5 ビットによっお䞎えられたす。 ぀たり、シフト カりントは count & 0x1F から蚈算されたす。 これは、 x の型が nint たたは nuintであり、それらの型のサむズず衚珟が、それぞれ int および uintず同じである堎合にも適甚されたす。
  • x の型が long たたは ulongの堎合、シフト カりントは count の䞋䜍 6 ビットによっお䞎えられたす。 ぀たり、シフト カりントは count & 0x3F から蚈算されたす。 これは、 x の型が nint たたは nuintであり、それらの型のサむズず衚珟が、それぞれ long および ulongず同じである堎合にも適甚されたす。

結果のシフト カりントが 0 の堎合、シフト挔算子は単に x の倀を返したす。

シフト挔算が原因でオヌバヌフロヌが発生するこずはなく、checked ず unchecked のコンテキストで同じ結果が生成されるこずはありたせん。

>> 挔算子の巊オペランドが笊号付き敎数型の堎合、挔算子は右に算術シフト を実行したす。ここで、オペランドの最䞊䜍ビット笊号ビットの倀は、高䜍の空のビット䜍眮に䌝達されたす。 >> 挔算子の巊オペランドが笊号なし敎数型の堎合、挔算子は右方向に 論理 シフトを実行したす。ここで、䞊䜍の空のビット䜍眮は垞に 0 に蚭定されたす。 オペランド型から掚論された逆の挔算を実行するには、明瀺的なキャストを䜿甚できたす。

䟋: x が int型の倉数である堎合、挔算 unchecked ((int)((uint)x >> y)) は xの論理シフト右を実行したす。 終了サンプル

䞊蚘で定矩されおいるリフトされおいない定矩枈みのシフト挔算子のリフトされた圢匏 (§12.4.8) も事前定矩されおいたす。

12.15 関係挔算子ず型テスト挔算子

12.15.1 党般

==、 !=、 <、 >、 <=、 >=、 is、および as 挔算子は、リレヌショナル挔算子ず型テスト挔算子ず呌ばれたす。

relational_expression
    : shift_expression
    | relational_expression '<' shift_expression
    | relational_expression '>' shift_expression
    | relational_expression '<=' shift_expression
    | relational_expression '>=' shift_expression
    | relational_expression 'is' type
    | relational_expression 'is' pattern
    | relational_expression 'as' type
    ;

equality_expression
    : relational_expression
    | equality_expression '==' relational_expression
    | equality_expression '!=' relational_expression
    ;

"relational_expressiontype" ず "isconstant_pattern" の䞡方の代替候補が適甚され、型がアクセス可胜な型に解決される堎合は、relational_expression (is) を認識する堎合は、"relational_expressionis" の代替候補が遞択されたす。

is挔算子は §12.15.12 で説明され、as挔算子は §12.15.13 で説明されおいたす。

==、 !=、 <、 >、 <= および >= の挔算子は、 比范挔算子です。

default_literal (§12.8.21) が <、 >、 <=、たたは >= 挔算子のオペランドずしお䜿甚されおいる堎合、コンパむル時゚ラヌが発生したす。 default_literal が == たたは != 挔算子の䞡方のオペランドずしお䜿甚されおいる堎合、コンパむル時゚ラヌが発生したす。 たたは is 挔算子の巊オペランドずしお as を䜿甚するず、コンパむル時゚ラヌが発生したす。

比范挔算子のオペランドにコンパむル時の型 dynamicがある堎合、匏は動的にバむンドされたす (§12.3.3)。 この堎合、匏のコンパむル時の型は dynamic であり、コンパむル時の型 dynamic を持぀オペランドの実行時の型を䜿甚しお、実行時に以䞋で説明する解決が行われたす。

フォヌム x Â«op» yの挔算の堎合、«op» は比范挔算子であり、オヌバヌロヌドの解決 (§12.4.5) が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。 equality_expression の䞡方のオペランドが null リテラルの堎合、オヌバヌロヌドの解決は実行されず、挔算子が true か false かに応じお、匏は == たたは != の定数倀に評䟡されたす。

定矩枈みの比范挔算子に぀いおは、次のサブクロヌズで説明したす。 次の衚に瀺すように、定矩枈みのすべおの比范挔算子はブヌル型の結果を返したす。

操䜜 結果
x == y trueが xに等しい堎合は y それ以倖の堎合は false。
x != y true が x ず等しくない堎合は y。それ以倖の堎合は false。
x < y true が x より小さい堎合は y、それ以倖の堎合は false
x > y true が x より倧きい堎合は y、それ以倖の堎合は false
x <= y true が x 以䞋の堎合は y、それ以倖の堎合は false
x >= y true が x 以䞊の堎合は y、それ以倖の堎合は false

12.15.2 敎数比范挔算子

定矩枈みの敎数比范挔算子は次のずおりです。

bool operator ==(int x, int y);
bool operator ==(uint x, uint y);
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);
bool operator ==(long x, long y);
bool operator ==(ulong x, ulong y);

bool operator !=(int x, int y);
bool operator !=(uint x, uint y);
bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);
bool operator !=(long x, long y);
bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);
bool operator <(uint x, uint y);
bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);
bool operator <(long x, long y);
bool operator <(ulong x, ulong y);

bool operator >(int x, int y);
bool operator >(uint x, uint y);
bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);
bool operator >(long x, long y);
bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);
bool operator <=(uint x, uint y);
bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);
bool operator <=(long x, long y);
bool operator <=(ulong x, ulong y);

bool operator >=(int x, int y);
bool operator >=(uint x, uint y);
bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);
bool operator >=(long x, long y);
bool operator >=(ulong x, ulong y);

これらの各挔算子は、2 ぀の敎数オペランドの数倀を比范し、特定の関係が bool か true かを瀺す false 倀を返したす。

䞊蚘で定矩されおいる未リフトの敎数比范挔算子のリフトされた圢匏 (§12.4.8) も事前に定矩されおいたす。

12.15.3 浮動小数点比范挔算子

定矩枈みの浮動小数点比范挔算子は次のずおりです。

bool operator ==(float x, float y);
bool operator ==(double x, double y);

bool operator !=(float x, float y);
bool operator !=(double x, double y);

bool operator <(float x, float y);
bool operator <(double x, double y);

bool operator >(float x, float y);
bool operator >(double x, double y);

bool operator <=(float x, float y);
bool operator <=(double x, double y);

bool operator >=(float x, float y);
bool operator >=(double x, double y);

挔算子は、IEC 60559 暙準の芏則に埓っおオペランドを比范したす。

いずれかのオペランドが NaN の堎合、結果が false の != 以倖のすべおの挔算子の結果が true になりたす。 2 ぀のオペランドの堎合、 x != y は垞に !(x == y)ず同じ結果を生成したす。 ただし、䞀方たたは䞡方のオペランドが NaN の堎合、<、>、<= の堎合、>= 挔算子は、反察の挔算子の論理吊定ず同じ結果を生成したせん。

䟋: x ず y のいずれかが NaN の堎合、 x < y は falseですが、 !(x >= y) は trueです。 終了サンプル

どちらのオペランドも NaN でない堎合、挔算子は 2 ぀の浮動小数点オペランドの倀を順序付けず比范したす

-∞ < -max < ... < -min < -0.0 == +0.0 < +min < ... < +max < +∞

ここで、 min ず max は、指定された浮動小数点圢匏で衚すこずができる最小および最倧の正の有限倀です。 この順序の䞻な圱響は次のずおりです。

  • 負のれロず正のれロは等しいず芋なされる。
  • 負の無限倧は、他のすべおの倀より小さいず芋なされたすが、別の負の無限倧ず等しくなりたす。
  • 正の無限倧は、他のすべおの倀より倧きいず芋なされたすが、別の正の無限倧ず等しくなりたす。

䞊蚘で定矩されおいる未リフトの定矩枈み浮動小数点比范挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.15.4 10 進数比范挔算子

定矩枈みの 10 進比范挔算子は次のずおりです。

bool operator ==(decimal x, decimal y);
bool operator !=(decimal x, decimal y);
bool operator <(decimal x, decimal y);
bool operator >(decimal x, decimal y);
bool operator <=(decimal x, decimal y);
bool operator >=(decimal x, decimal y);

これらの各挔算子は、2 ぀の10進オペランドの数倀を比范し、特定の関係が bool か true かを瀺す false 倀を返したす。 各 10 進比范は、 System.Decimal型の察応するリレヌショナル挔算子たたは等倀挔算子を䜿甚するこずず同じです。

䞊蚘で定矩されおいる未リフトの定矩枈み小数比范挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.15.5 ブヌル等倀挔算子

定矩枈みのブヌル等倀挔算子は次のずおりです。

bool operator ==(bool x, bool y);
bool operator !=(bool x, bool y);

== ず true の䞡方が x の堎合、たたは y ず true の䞡方が x の堎合、 y の結果は false になりたす。 それ以倖の堎合、結果は false です。

!= ず false の䞡方が x の堎合、たたは y ず true の䞡方が x の堎合、 y の結果は false になりたす。 それ以倖の堎合、結果は true です。 オペランドが bool型の堎合、 != 挔算子は ^ 挔算子ず同じ結果を生成したす。

䞊蚘で定矩した、未リフトの定矩枈みブヌル等倀挔算子のリフトバヌゞョン (§12.4.8) も定矩枈みです。

12.15.6 列挙比范挔算子

すべおの列挙型は、次の定矩枈みの比范挔算子を暗黙的に提䟛したす。

bool operator ==(E x, E y);
bool operator !=(E x, E y);

bool operator <(E x, E y);
bool operator >(E x, E y);
bool operator <=(E x, E y);
bool operator >=(E x, E y);

x Â«op» yを評䟡した結果 (x ず y は基になる型 E を持぀列挙型 U の匏であり、«op» は比范挔算子の 1 ぀であり、 ((U)x) Â«op» ((U)y)の評䟡ずたったく同じです。 ぀たり、列挙型の比范挔算子は、単に 2 ぀のオペランドの基になる敎数倀を比范したす。

䞊蚘で定矩されおいる未リフトの定矩枈み列挙比范挔算子のリフト (§12.4.8) 圢匏も事前定矩されおいたす。

12.15.7 参照型の等倀挔算子

すべおのクラス型 C は、次の定矩枈みの参照型の等倀挔算子を暗黙的に提䟛したす。

bool operator ==(C x, C y);
bool operator !=(C x, C y);

定矩枈みの等倀挔算子が C に存圚しない限り (たずえば、 C が string たたは System.Delegateの堎合)。

䞡方のオペランドがレコヌド クラスであるか、䞡方が非レコヌド クラスである必芁がありたす。

挔算子は、等しいか等しくないかの 2 ぀の参照を比范した結果を返したす。

レコヌド以倖のクラスオペランドの堎合、operator ==は、trueずxが同じむンスタンスを参照しおいる堎合、たたは䞡方がy堎合にのみnullを返したすが、operator !=は、同じオペランドを持぀trueがoperator ==を返す堎合にのみfalseを返したす。

レコヌド クラス オペランドの堎合、operator ==は、2 ぀のレコヌド クラスずその基底レコヌド クラス内のすべおの察応するむンスタンス フィヌルドの倀が等しい堎合、たたは䞡方の参照がtrue堎合にのみnullを返したすが、同じオペランドを持぀operator !=がtrueを返す堎合にのみ、operator ==はfalseを返したす。

暙準の適甚芏則 (§12.6.4.2) に加えお、定矩枈みの参照型の等倀挔算子を適甚するには、次のいずれかが必芁です。

  • どちらのオペランドも、 reference_type たたはリテラル nullであるこずが知られおいる型の倀です。 さらに、いずれかのオペランドから他方のオペランドの型に察する ID たたは明瀺的な参照倉換 (§10.3.5) が存圚したす。
  • 䞀方のオペランドはリテラル nullで、もう 1 ぀のオペランドは T 型の倀です。ここで、 T は倀型ずは認識されず、倀型制玄を持たない type_parameter です。
    • 実行時 T が null 非蚱容倀型の堎合、 == の結果は false され、 != の結果は trueです。
    • 実行時 T が null 蚱容倀型の堎合、結果はオペランドの HasValue プロパティから蚈算されたす (§12.15.10)。
    • 実行時に T が参照型の堎合、オペランドが true であれば結果は null になり、それ以倖の堎合は false になりたす。

これらの条件のいずれかが圓おはたる堎合を陀き、バむンド時゚ラヌが発生したす。

泚意: これらのルヌルの䞻な圱響は次のずおりです。

  • 定矩枈みの参照型の等倀挔算子を䜿甚しお、バむンド時に異なるこずがわかっおいる 2 ぀の参照を比范するのは、バむンド時゚ラヌです。 たずえば、オペランドのバむンディング時の型が 2 ぀のクラス型であり、どちらも他方から掟生しおいない堎合、2 ぀のオペランドが同じオブゞェクトを参照するこずはできたせん。 したがっお、挔算はバむンド時゚ラヌず芋なされたす。
  • 定矩枈みの参照型の等倀挔算子では、倀型オペランドの比范は蚱可されたせん (型パラメヌタヌが特別に凊理される nullず比范される堎合を陀く)。
  • 定矩枈みの参照型の等倀挔算子のオペランドはボックス化されたせん。 新しく割り圓おられたボックス化されたむンスタンスぞの参照は、必ずしも他のすべおの参照ず異なるため、このようなボックス化挔算を実行するこずは意味がありたせん。

フォヌム x == y たたは x != yの挔算で、該圓するナヌザヌ定矩の operator == たたは operator != が存圚する堎合、挔算子オヌバヌロヌド解決芏則 (§12.4.5) は、定矩枈みの参照型の等倀挔算子ではなく、その挔算子を遞択したす。 オペランドの䞀方たたは䞡方を型 objectに明瀺的にキャストするこずで、垞に定矩枈みの参照型の等倀挔算子を遞択できたす。

泚釈

䟋: 次の䟋では、制玄のない型パラメヌタヌ型の匕数が nullされおいるかどうかを確認したす。

class C<T>
{
   void F(T x)
   {
      if (x == null)
      {
          throw new ArgumentNullException();
      }
      ...
   }
}

x == null コンストラクトは、 T が null 非蚱容倀型を衚すこずができる堎合でも蚱可され、 false が null 非蚱容倀型の堎合に T するように結果が単玔に定矩されたす。

終了サンプル

フォヌム x == y たたは x != yの挔算で、該圓するナヌザヌ定矩の operator == たたは operator != が存圚する堎合、挔算子オヌバヌロヌド解決 (§12.4.5) 芏則は、定矩枈みの参照型の等倀挔算子ではなく、その挔算子を遞択したす。

泚: 䞡方のオペランドを明瀺的に型 objectにキャストするこずで、定矩枈みの参照型等倀挔算子を遞択するこずが垞に可胜です。 泚釈

䟋: その䟋

class Test
{
    static void Main()
    {
        string s = "Test";
        string t = string.Copy(s);
        Console.WriteLine(s == t);
        Console.WriteLine((object)s == t);
        Console.WriteLine(s == (object)t);
        Console.WriteLine((object)s == (object)t);
    }
}

出力を生成したす。

True
False
False
False

s 倉数ず t 倉数は、同じ文字を含む 2 ぀の異なる文字列むンスタンスを参照したす。 最初の比范では、䞡方のオペランドがTrue型の堎合に定矩枈みの文字列等倀挔算子 (§12.15.8) が遞択されおいるため、string出力されたす。 残りの比范のすべおは、False を出力したす。なぜなら、operator == 型の string のオヌバヌロヌドは、いずれかのオペランドがバむンド時型の objectを持っおいる堎合には適甚されないからです。

䞊蚘の手法は、倀型では意味を持たないこずに泚意しおください。 䟋

class Test
{
    static void Main()
    {
        int i = 123;
        int j = 123;
        Console.WriteLine((object)i == (object)j);
    }
}

は、False を出力したす。これはキャストがボックス化された int 倀の 2 ぀の個別むンスタンスぞの参照を䜜成するためです。

終了サンプル

12.15.8 文字列等倀挔算子

定矩枈みの文字列等倀挔算子は次のずおりです。

bool operator ==(string x, string y);
bool operator !=(string x, string y);

次のいずれかが圓おはたる堎合、2 ぀の string 倀が等しいず芋なされたす。

  • どちらの倀も nullです。
  • どちらの倀も、各文字䜍眮に同じ長さず同じ文字を持぀文字列むンスタンスぞの非null 参照です。

文字列の等倀挔算子は、文字列参照ではなく文字列倀を比范したす。 2 ぀の個別の文字列むンスタンスにたったく同じ文字シヌケンスが含たれおいる堎合、文字列の倀は等しくなりたすが、参照は異なりたす。

泚: §12.15.7 で説明されおいるように、参照型の等倀挔算子を䜿甚しお、文字列倀の代わりに文字列参照を比范できたす。 泚釈

12.15.9 等倀挔算子を委任する

定矩枈みのデリゲヌト等倀挔算子は次のずおりです。

bool operator ==(System.Delegate x, System.Delegate y);
bool operator !=(System.Delegate x, System.Delegate y);

2 ぀のデリゲヌト むンスタンスは、次のように等しいず芋なされたす。

  • いずれかのデリゲヌト むンスタンスが nullである堎合、䞡方が nullである堎合にのみ、それらは等しくなりたす。
  • デリゲヌトに、異なる実行時の型がある堎合、それらが等しくなるこずはありたせん。
  • 䞡方のデリゲヌト むンスタンスに呌び出しリスト (§21.2) がある堎合、それらのむンスタンスは、呌び出しリストが同じ長さであり、1 ぀の呌び出しリスト内の各゚ントリが察応する゚ントリ (以䞋で定矩) ず等しい堎合にのみ、他方の呌び出しリスト内の順序で等しくなりたす。

次の芏則は、呌び出しリスト ゚ントリの等䟡性を制埡したす。

  • 2 ぀の呌び出しリスト 項目が䞡方ずも同じ静的メ゜ッドを参照しおいる堎合、項目は等しくなりたす。
  • 2 ぀の呌び出しリスト ゚ントリが䞡方ずも同じタヌゲット オブゞェクトで同じ非静的メ゜ッドを参照しおいる堎合 (参照等倀挔算子で定矩されおいる堎合)、゚ントリは等しくなりたす。
  • キャプチャされた倖郚倉数むンスタンスの同じ (空の可胜性がある) セットを持぀セマンティックに同䞀の匿名関数 (§12.22) の評䟡から生成された呌び出しリスト ゚ントリは、等しい (ただし必芁ありたせん) 蚱可されたす。

挔算子のオヌバヌロヌド解決がいずれかのデリゲヌト等倀挔算子に解決され、䞡方のオペランドのバむンド時型が、ではなくSystem.Delegate で説明されおいるデリゲヌト型であり、バむンド型オペランド型間に ID 倉換がない堎合、バむンド時゚ラヌが発生したす。

泚意: この芏則は、異なる皮類のデリゲヌト型むンスタンスを参照するため、非null 倀を等しいず芋なすこずができない比范を防ぐためのものです。 泚釈

12.15.10 null 蚱容倀型ず null リテラル間の等倀挔算子

事前定矩された挔算子やナヌザヌ定矩の挔算子が (未リフトたたはリフト圢匏に) その操䜜にない堎合でも、== および != 挔算子は、あるオペランドを null 蚱容倀型の倀にしお、別のオペランドを null リテラルにするこずができたす。

いずれかのフォヌムの挔算の堎合

x == null    null == x    x != null    null != x

ここで、 x は null 蚱容倀型の匏です。挔算子オヌバヌロヌドの解決 (§12.4.5) が該圓する挔算子を芋぀けられなかった堎合、結果は代わりに HasValue の x プロパティから蚈算されたす。 具䜓的には、最初の 2 ぀のフォヌムは !x.HasValueに倉換され、最埌の 2 ぀のフォヌムは x.HasValueに倉換されたす。

12.15.11 タプル等倀挔算子

タプル等倀挔算子は、タプル オペランドの芁玠に構文順にペアワむズで適甚されたす。

x 挔算子たたは y 挔算子の各オペランド == ず != がタプルたたはタプル型 (§8.3.11) の倀ずしお分類される堎合、挔算子は タプル等䟡挔算子です。

オペランド e がタプルずしお分類されおいる堎合、 e₁...eₙ 芁玠はタプル リテラルの芁玠匏を評䟡した結果になりたす。 それ以倖の堎合、 e がタプル型の倀である堎合、芁玠は t.Item1...t.Itemn ずなり、 t は e を評䟡した結果ずなりたす。

タプル等倀挔算子のオペランド x ず y は同じアリティを持぀必芁がありたす。たたは、コンパむル時゚ラヌが発生したす。 芁玠 xáµ¢ ず yᵢの各ペアに察しお、同じ等倀挔算子が適甚され、 bool、 dynamic、 boolぞの暗黙的な倉換を持぀型、たたは true 挔算子ず false 挔算子を定矩する型の結果が埗られたす。

タプル等倀挔算子 x == y は、次のように評䟡されたす。

  • 巊偎のオペランド x が評䟡されたす。
  • 右偎のオペランド y が評䟡されたす。
  • 蟞曞匏順序で xáµ¢ および yáµ¢ 芁玠のペアごずに、
    • 挔算子 xáµ¢ == yáµ¢ が評䟡され、 bool 型の結果が次のように取埗されたす。
      • 比范によっお bool が生成された堎合、それが結果になりたす。
      • それ以倖の堎合、比范によっお dynamic が生成された堎合、挔算子 false が動的に呌び出され、結果の bool 倀は論理吊定挔算子 (!) で吊定されたす。
      • それ以倖の堎合、比范の型に boolぞの暗黙的な倉換がある堎合、その倉換が適甚されたす。
      • それ以倖の堎合、比范の型に挔算子 falseがある堎合、その挔算子が呌び出され、結果の bool 倀は論理吊定挔算子 (!) で吊定されたす。
    • 結果の bool が falseである堎合、それ以䞊の評䟡は行われず、タプル等倀挔算子の結果は falseずなりたす。
  • すべおの芁玠の比范の結果が true を返した堎合、タプル等䟡挔算子の結果は true になりたす。

タプル等倀挔算子 x != y は、次のように評䟡されたす。

  • 巊偎のオペランド x が評䟡されたす。
  • 右偎のオペランド y が評䟡されたす。
  • 蟞曞匏順序で xáµ¢ および yáµ¢ 芁玠のペアごずに、
    • 挔算子 xáµ¢ != yáµ¢ が評䟡され、 bool 型の結果が次のように取埗されたす。
      • 比范によっお bool が生成された堎合、それが結果になりたす。
      • それ以倖の堎合、比范によっお dynamic が生成された堎合、挔算子 true が動的に呌び出され、結果の bool 倀が結果になりたす。
      • それ以倖の堎合、比范の型に boolぞの暗黙的な倉換がある堎合、その倉換が適甚されたす。
      • それ以倖の堎合、比范の型に挔算子 trueがある堎合、その挔算子が呌び出され、結果の bool 倀が結果になりたす。
    • 結果の bool が trueである堎合、それ以䞊の評䟡は行われず、タプル等倀挔算子の結果は trueずなりたす。
  • すべおの芁玠の比范の結果が false を返した堎合、タプル等䟡挔算子の結果は false になりたす。

12.15.12 Is 挔算子

is 挔算子には 2 ぀の圢匏がありたす。 ひず぀は、is-type operator で、右偎に型がありたす。 もうひず぀は、is-pattern operator で、右偎にパタヌンがありたす。

12.15.12.1 is-type 挔算子

is-type 挔算子 は、オブゞェクトの実行時の型が特定の型ず互換性があるかどうかを確認するために䜿甚されたす。 チェックは実行時に実行されたす。 E is T が匏であり、 E が T以倖の型である挔算 dynamicの結果は、 E が null 以倖であり、参照倉換、ボックス化倉換、ボックス化解陀倉換、ラップ解陀倉換によっお T 型に正垞に倉換できるかどうかを瀺すブヌル倀です。

操䜜 E is T は次のように評䟡されたす。

  1. E が匿名関数たたはメ゜ッド グルヌプの堎合は、コンパむル時゚ラヌが発生したす。
  2. Tが null 蚱容参照型 (§8.9.3) の堎合、コンパむル時゚ラヌが発生したす。
  3. E が null リテラルの堎合、たたは E の倀が nullである堎合、結果は falseずなりたす。
  4. それ以倖の堎合:
    1. R を Eのランタむム型にしたしょう。
    2. D 型を決定したす。 R が null 蚱容倀型の堎合、 D はその基になる型です。それ以倖の堎合、 D は Rず等しくなりたす。
    3. 結果は、次のように D ず T によっお異なりたす。
      1. T が参照型であれば、以䞋の堎合に結果は true ずなりたす。
        • DずTの間に ID 倉換が存圚する、たたは
        • D は参照型であり、 D から T ぞの暗黙的な参照倉換が存圚する、たたは
        • D は倀型であり、 D から T ぞのボックス化倉換が存圚したす。
      2. T が null 蚱容倀型の堎合、 true が D の基になる型であれば、結果は T ずなりたす。
      3. T が null 非蚱容倀型の堎合、 true ず D が同じ型の堎合、結果は T ずなりたす。
      4. それ以倖の堎合、結果は false です。

ナヌザヌ定矩の倉換は、 is 挔算子からは考慮されたせん。

泚意: is 挔算子は実行時に評䟡されるため、すべおの型匕数が眮換されおおり、考慮すべきオヌプン型 (§8.4.3) はありたせん。 泚釈

泚意: is 挔算子は、次のようにコンパむル時の型ず倉換の芳点から理解できたす。ここで、 C は Eのコンパむル時の型です。

  • e のコンパむル時の型が T ず同じである堎合、たたは のコンパむル時の型から ぞの暗黙的な参照倉換 (§10.2.8)、ボックス化倉換 (§10.2.9)、ラッピング倉換 (E)、たたは明瀺的なアンラッピング倉換 (T) が存圚する堎合:
    • C が null 非蚱容倀型の堎合、挔算の結果は trueずなりたす。
    • それ以倖の堎合、挔算の結果は E != nullの評䟡ず同じです。
  • それ以倖の堎合、明瀺的な参照倉換 (§10.3.5) たたはボックス化解陀倉換 (§10.3.7) が C から Tに存圚する堎合、たたは C たたは T がオヌプン型 (§8.4.3) の堎合は、䞊蚘のランタむム チェックが実行されたす。
  • それ以倖の堎合は、 E から型 T ぞの参照、ボックス化、折り返し、たたはラップ解陀の倉換はできず、挔算の結果は falseずなりたす。 コンパむラは、コンパむル時の型に基づいお最適化を実装できたす。

泚釈

12.15.12.2 is-pattern 挔算子

is-pattern 挔算子 は、匏 によっお蚈算された倀が特定のパタヌン (§11) ず 䞀臎する かどうかを確認するために䜿甚されたす。 チェックは実行時に実行されたす。 倀がパタヌンず䞀臎する堎合、is-pattern 挔算子の結果は true になりたす。それ以倖の堎合は false です。

フォヌム E is Pの匏の堎合(ここで E は T 型の関係匏で、 P はパタヌンです。次のいずれかが保持されおいる堎合、コンパむル時゚ラヌになりたす。

  • E は倀を指定しないか、型を持っおいたせん。
  • パタヌン P は、 型 に適甚できたせん (T)。

パタヌンのすべおのsingle_variable_designationでは、察応するrelational_expressionテストがされたずきに確実に割り圓おられる新しいロヌカル倉数 (true) が導入されたす (§9.4.4.34)。

12.15.13 as 挔算子

as 挔算子は、倀を特定の参照型たたは null 蚱容倀型に明瀺的に倉換するために䜿甚されたす。 キャスト匏 (§12.9.8) ずは異なり、 as 挔算子は䟋倖をスロヌしたせん。 代わりに、指定された倉換が䞍可胜な堎合、結果の倀は nullです。

圢匏 E as T の挔算では、 E は匏であり、 T は参照型、参照型ずしお認識されおいる型パラメヌタヌ、たたは null 蚱容倀型である必芁がありたす。 さらに、次のうち少なくずも 1 ぀が true であるか、それ以倖の堎合はコンパむル時゚ラヌが発生したす。

  • 識別子 (§10.2.2)、暗黙的なnullable (§10.2.6)、暗黙的参照 (§10.2.8)、ボックス化 (§10.2.9)、明瀺的なnullable (§10.3.4)、明瀺的参照 (§10.3.5)、たたはラッピング倉換 (§8.3.12) がEからTぞの倉換ずしお存圚したす。
  • E たたは T の型は開いおいる型です。
  • E は null のリテラルです。

E のコンパむル時の型が dynamicでない堎合、挔算 E as T は以䞋ず同じ結果を生成したす

E is T ? (T)(E) : (T)null

ただし、E が評䟡されるのは 1 回だけです。 コンパむラは、䞊蚘の拡匵によっお瀺される 2 ぀のランタむム型チェックずは察照的に、最倧 1 ぀のランタむム型チェックを実行するように E as T を最適化するこずが期埅できたす。

キャスト挔算子ずは異なり、 E のコンパむル時の型が dynamicである堎合、 as 挔算子は動的にバむンドされたせん (§12.3.3)。 したがっお、この堎合の拡匵は次のずおりです。

E is T ? (T)(object)(E) : (T)null

ナヌザヌ定矩倉換などの䞀郚の倉換は、 as 挔算子では実行できないため、代わりにキャスト匏を䜿甚しお実行する必芁があるこずに泚意しおください。

䟋: この䟋では

class X
{
    public string F(object o)
    {
        return o as string;  // OK, string is a reference type
    }

    public T G<T>(object o)
        where T : Attribute
    {
        return o as T;       // Ok, T has a class constraint
    }

    public U H<U>(object o)
    {
        return o as U;       // Error, U is unconstrained
    }
}

T の型パラメヌタヌ G は、クラス制玄があるため、参照型であるこずがわかっおいたす。 ただし、 U の型パラメヌタヌ H はありたせん。そのため、 as での H 挔算子の䜿甚は蚱可されたせん。

終了サンプル

12.16 論理挔算子

12.16.1 党般

&、^、および | 挔算子は論理挔算子ず呌ばれたす。

and_expression
    : equality_expression
    | and_expression '&' equality_expression
    ;

exclusive_or_expression
    : and_expression
    | exclusive_or_expression '^' and_expression
    ;

inclusive_or_expression
    : exclusive_or_expression
    | inclusive_or_expression '|' exclusive_or_expression
    ;

論理挔算子のオペランドにコンパむル時の型 dynamicがある堎合、匏は動的にバむンドされたす (§12.3.3)。 この堎合、匏のコンパむル時の型は dynamic であり、コンパむル時の型 dynamic を持぀オペランドの実行時の型を䜿甚しお、実行時に以䞋で説明する解決が行われたす。

フォヌム x Â«op» yの挔算「op」は論理挔算子の1぀の堎合、オヌバヌロヌドの解決§12.4.5が適甚され、特定の挔算子の実装が遞択されたす。 オペランドは遞択した挔算子のパラメヌタヌ型に倉換され、結果の型は挔算子の戻り倀の型になりたす。

定矩枈みの論理挔算子に぀いおは、次のサブクロヌズで説明したす。

12.16.2 敎数論理挔算子

定矩枈みの敎数論理挔算子は次のずおりです。

int operator &(int x, int y);
uint operator &(uint x, uint y);
nint operator &(nint x, nint y);
nuint operator &(nuint x, nuint y);
long operator &(long x, long y);
ulong operator &(ulong x, ulong y);

int operator |(int x, int y);
uint operator |(uint x, uint y);
nint operator |(nint x, nint y);
nuint operator |(nuint x, nuint y);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);

int operator ^(int x, int y);
uint operator ^(uint x, uint y);
nint operator ^(nint x, nint y);
nuint operator ^(nuint x, nuint y);
long operator ^(long x, long y);
ulong operator ^(ulong x, ulong y);

& 挔算子は、2 ぀のオペランドのビットごずの論理 AND を蚈算し、 | 挔算子は 2 ぀のオペランドのビットごずの論理 OR を蚈算し、 ^ 挔算子は 2 ぀のオペランドのビットごずの論理排他的 OR を蚈算したす。 これらの挔算からのオヌバヌフロヌは発生したせん。

䞊蚘で定矩されおいる未リフトの定矩枈み敎数論理挔算子のリフトされた (§12.4.8) 圢匏もあらかじめ定矩されおいたす。

12.16.3 列挙論理挔算子

すべおの列挙型 E は、次の定矩枈みの論理挔算子を暗黙的に提䟛したす。

E operator &(E x, E y);
E operator |(E x, E y);
E operator ^(E x, E y);

x Â«op» y を評䟡した結果は、 x ず y が基瀎型 E を持぀列挙型 U の匏であり、«op» が論理挔算子の 1 ぀である堎合、 (E)((U)x Â«op» (U)y) を評䟡した結果ずたったく同じになりたす。 ぀たり、列挙型の論理挔算子は、2 ぀のオペランドの基になる型に察しお論理挔算を実行するだけです。

䞊蚘で定矩されおいる未リフトの定矩枈み列挙論理挔算子のリフトされた圢匏 (§12.4.8) もあらかじめ定矩されおいたす。

12.16.4 ブヌル論理挔算子

定矩枈みのブヌル論理挔算子は次のずおりです。

bool operator &(bool x, bool y);
bool operator |(bool x, bool y);
bool operator ^(bool x, bool y);

x & y ず true の䞡方が x であれば、y の結果は true です。 それ以倖の堎合、結果は false です。

x | y たたは true のいずれかが x の堎合、 y の結果は true になりたす。 それ以倖の堎合、結果は false です。

x ^ y が true であり x が trueの堎合、たたは y が false であり x が falseの堎合、y の結果は true になりたす。 それ以倖の堎合、結果は false です。 オペランドが bool型の堎合、 ^ 挔算子は != 挔算子ず同じ結果を蚈算したす。

12.16.5 Null 蚱容ブヌル倀 & |挔算子

nullable ブヌル型 bool? は、true、false、および nullの 3 ぀の倀を衚すこずができたす。

他の二項挔算子ず同様に、論理挔算子の & ず | (§12.16.4) のリフトされた圢匏も事前に定矩されおいたす。

bool? operator &(bool? x, bool? y);
bool? operator |(bool? x, bool? y);

リフトされた & 挔算子ず | 挔算子のセマンティクスは、次の衚で定矩したす。

x y x & y x \| y
true true true true
true false false true
true null null true
false true false true
false false false false
false null false null
null true null true
null false false null
null null null null

泚意: bool? 型は抂念的には、SQL のブヌル匏に䜿甚される 3 ぀の倀の型に䌌おいたす。 䞊の衚は SQL ず同じセマンティクスに埓いたす。䞀方、 §12.4.8 の芏則を & および | 挔算子には適甚したせん。 §12.4.8 の芏則では、リフトされた ^ 挔算子に察しお SQL に䌌たセマンティクスが既に提䟛されおいたす。 泚釈

12.17 条件付き論理挔算子

12.17.1 党般

&& 挔算子ず || 挔算子は、条件付き論理挔算子ず呌ばれたす。 これらは、"短絡" 論理挔算子ずも呌ばれたす。

conditional_and_expression
    : inclusive_or_expression
    | conditional_and_expression '&&' inclusive_or_expression
    ;

conditional_or_expression
    : conditional_and_expression
    | conditional_or_expression '||' conditional_and_expression
    ;

&& 挔算子ず || 挔算子は、 & 挔算子ず | 挔算子の条件付きバヌゞョンです。

  • 挔算 x && y は、挔算 x & yに察応したす。ただし、 y は x が falseされおいない堎合にのみ評䟡されたす。
  • 挔算 x || y は、挔算 x | yに察応したす。ただし、 y は x が trueされおいない堎合にのみ評䟡されたす。

泚: ショヌトサヌキットで "not true" 条件ず "not false" 条件が䜿甚される理由は、ナヌザヌ定矩の条件付き挔算子でショヌトサヌキットが適甚されるタむミングを定矩できるようにするためです。 ナヌザヌ定矩型は、 operator true が false を返し、 operator false が falseを返す状態になる可胜性がありたす。 そのような堎合、&& も || も短瞮したせん。 泚釈

条件論理挔算子のオペランドにコンパむル時の型 dynamicがある堎合、匏は動的にバむンドされたす (§12.3.3)。 この堎合、匏のコンパむル時の型は dynamic であり、コンパむル時の型 dynamic を持぀オペランドの実行時の型を䜿甚しお、実行時に以䞋で説明する解決が行われたす。

x && y たたは x || y 圢匏の挔算は、 たたは x & y ず蚘述されたかのようにオヌバヌロヌド解決x | yを適甚するこずによっお凊理されたす。 このずき、次のようになりたす。

  • オヌバヌロヌドの解決で 1 ぀の最適な挔算子が芋぀からない堎合、たたはオヌバヌロヌド解決で定矩枈みの敎数論理挔算子たたは null 蚱容ブヌル論理挔算子 (§12.16.5) のいずれかを遞択するず、バむンド時゚ラヌが発生したす。
  • それ以倖の堎合、遞択した挔算子が定矩枈みのブヌル論理挔算子 (§12.16.4) の 1 ぀である堎合、操䜜は §12.17.2 で説明されおいるように凊理されたす。
  • それ以倖の堎合、遞択した挔算子はナヌザヌ定矩挔算子であり、 操䜜は §12.17.3 で説明されおいるように凊理されたす。

条件付き論理挔算子を盎接オヌバヌロヌドするこずはできたせん。 ただし、条件付き論理挔算子は通垞の論理挔算子の芳点から評䟡されるため、通垞の論理挔算子のオヌバヌロヌドは、特定の制限があり、条件付き論理挔算子のオヌバヌロヌドずも芋なされたす。 これに぀いおは、 §12.17.3 で詳しく説明したす。

12.17.2 ブヌル条件論理挔算子

&& たたは || のオペランドが bool型の堎合、たたはオペランドが該圓する operator & たたは operator |を定矩しないが、 boolぞの暗黙的な倉換を定矩する型の堎合、挔算は次のように凊理されたす。

  • 挔算 x && y は、 x ? y : falseずしお評䟡されたす。 ぀たり、たず x が評䟡され、 bool型に倉換されたす。 次に、もし x が true である堎合、 y が評䟡され、 bool 型に倉換され、その結果が挔算の結果ずなりたす。 それ以倖の堎合、挔算の結果は falseです。
  • 挔算 x || y は、 x ? true : yずしお評䟡されたす。 ぀たり、たず x が評䟡され、 bool型に倉換されたす。 次に、 x が trueである堎合、挔算の結果は trueです。 それ以倖の堎合、 y が評䟡され、 bool型に倉換され、その結果が挔算の結果ずなりたす。

12.17.3 ナヌザヌ定矩の条件付き論理挔算子

&& たたは || のオペランドが、適甚可胜なナヌザヌ定矩の operator & たたは operator |を宣蚀する型である堎合、次の䞡方が true になりたす。ここで、 T は、遞択した挔算子が宣蚀されおいる型です。

  • 遞択した挔算子の戻り型ず各パラメヌタヌの型はTでなければなりたせん。 ぀たり、挔算子は、 T型の 2 ぀のオペランドの論理 AND たたは論理 OR を蚈算し、 T型の結果を返したす。
  • T には、 operator true ず operator falseの宣蚀が含たれおいる必芁がありたす。

これらの芁件のいずれかが満たされおいない堎合、バむンド時゚ラヌが発生したす。 それ以倖の堎合、 && たたは || 挔算は、ナヌザヌ定矩の operator true たたは operator false を遞択したナヌザヌ定矩挔算子ず組み合わせるこずによっお評䟡されたす。

  • 挔算 x && y は T.false(x) ? x : T.&(x, y)ずしお評䟡されたす。ここで、 T.false(x) は operator false で宣蚀された T の呌び出しであり、 T.&(x, y) は遞択した operator &の呌び出しです。 ぀たり、 x が最初に評䟡され、結果に察しお operator false が呌び出され、x が確実に false であるかどうかを刀断したす。 次に、 x が間違いなく false の堎合、挔算の結果は、 xに察しお以前に蚈算された倀になりたす。 それ以倖の堎合は、 y が評䟡され、遞択した operator & が、 x に察しお以前に蚈算された倀ず、挔算の結果を生成するために y のために蚈算された倀に察しお呌び出されたす。
  • 挔算 x || y は T.true(x) ? x : T.|(x, y)ずしお評䟡されたす。ここで、 T.true(x) は operator true で宣蚀された T の呌び出しであり、 T.|(x, y) は遞択した operator |の呌び出しです。 ぀たり、 x が最初に評䟡され、結果に察しお operator true が呌び出され、 x が確実に true であるかどうかを刀断したす。 次に、 x が間違いなく true の堎合、挔算の結果は、 xに察しお以前に蚈算された倀になりたす。 それ以倖の堎合は、 y が評䟡され、遞択した operator | が、 x に察しお以前に蚈算された倀ず、挔算の結果を生成するために y のために蚈算された倀に察しお呌び出されたす。

いずれの挔算でも、 x によっお指定された匏は 1 回だけ評䟡され、 y によっお指定された匏は評䟡されず、1 回だけ評䟡もされたせん。

12.18 null 合䜓挔算子

?? 挔算子は、null 合䜓挔算子ず呌ばれたす。

null_coalescing_expression
    : conditional_or_expression
    | conditional_or_expression '??' null_coalescing_expression
    | throw_expression
    ;

a ?? bの圢匏のnull結合匏で、もし a が非nullであれば、結果は aずなり、そうでなければ結果は bずなりたす。 挔算は、 b が a である堎合にのみ、 null を評䟡したす。

null 合䜓挔算子は右連想です。぀たり、挔算は右から巊にグルヌプ化されたす。

䟋: a ?? b ?? c 圢匏の匏を a ?? (b ?? c)ずしお評䟡したす。 䞀般的に、圢匏 E1 ?? E2 ?? ... ?? EN の匏は、null 以倖の最初のオペランドを返したす。すべおのオペランドが null の堎合は null を返したす。 終了サンプル

a ?? b 匏の型は、オペランドで䜿甚できる暗黙的な倉換によっお異なりたす。 優先順に、a ?? b の型は A₀、A、たたは Bです。ただし、A が型を持぀堎合は a が a の型であり、B が型を持぀堎合は b が bの型です。たた、A₀ がnull蚱容倀型の堎合、A は A の基になる型、それ以倖の堎合は A です。 具䜓的には、 a ?? b は次のように凊理されたす。

  • Aが存圚し、null 非蚱容倀型たたは安党でないコヌド内のポむンタヌ型である堎合は、コンパむル時゚ラヌが発生したす。
  • それ以倖の堎合、 A が存圚し、 b が動的な匏である堎合、結果の型は dynamicです。 実行時に、 a が最初に評䟡されたす。 a が nullでない堎合、 a は dynamicに倉換され、これが結果になりたす。 それ以倖の堎合は、 b が評䟡され、これが結果になりたす。
  • それ以倖の堎合、 A が存圚し、null 蚱容倀型であり、 b から A₀ぞの暗黙的な倉換が存圚する堎合、結果の型は A₀です。 実行時に、 a が最初に評䟡されたす。 a が nullでない堎合、a は A₀型に展開され、これが結果になりたす。 それ以倖の堎合、 b が評䟡され、 A₀型に倉換され、これが結果になりたす。
  • それ以倖の堎合、 A が存圚し、 b から Aぞの暗黙的な倉換が存圚する堎合、結果の型は Aです。 実行時に、 a が最初に評䟡されたす。 a が nullされおいない堎合、a 結果になりたす。 それ以倖の堎合、 b が評䟡され、 A型に倉換され、これが結果になりたす。
  • それ以倖の堎合、 A が存圚し、null 蚱容倀型であり、 b の型が B であり、 A₀ から B ぞの暗黙的な倉換が存圚する堎合、結果の型は B になりたす。 実行時に、 a が最初に評䟡されたす。 a が nullではない堎合、 a は A₀ 型にラップ解陀され、 B型に倉換され、これが結果になりたす。 それ以倖 の堎合、 b が評䟡され、これが結果ずなりたす。
  • それ以倖の堎合、 b に型 B があり、 a から Bぞの暗黙的な倉換が存圚する堎合、結果の型は Bずなりたす。 実行時に、 a が最初に評䟡されたす。 a が nullでない堎合、 a は B型に倉換され、これが結果になりたす。 それ以倖 の堎合、 b が評䟡され、これが結果ずなりたす。
  • それ以倖の堎合、a ず b に互換性がありたせん。コンパむル時゚ラヌが発生したす。

䟋:

T M<T>(T a, T b) => a ?? b;

string s = M(null, "text");
int i = M(19, 23);

メ゜ッド Tの型パラメヌタヌMは制玄されおいたせん。 したがっお、 Mの最初の呌び出しに瀺すように、型匕数には参照型たたは null 蚱容倀型を指定できたす。 Mの 2 番目の呌び出しに瀺すように、型匕数には null 非蚱容倀型を指定するこずもできたす。 型匕数が null 非蚱容倀型の堎合、匏 a ?? b の倀は a。

終了サンプル

12.19 throw 匏挔算子

throw_expression
    : 'throw' null_coalescing_expression
    ;

throw_expression は、null_coalescing_expressionを評䟡するこずによっお生成された倀を投げたす。 匏は暗黙的に System.Exceptionに倉換でき、匏を評䟡した結果はスロヌされる前に System.Exception に倉換されたす。 throw 匏 の評䟡実行時の動䜜は、 throw ステヌトメント (§13.10.6) に指定されおいるものず同じです。

throw_expression に型はありたせん。 throw_expression は、暗黙的スロヌ倉換によっおどの型にも倉換できたす。

throw 匏 は、次の構文䞊のコンテキストでのみ䜿甚されるべきです。

  • 䞉項条件挔算子 (?:) の 2 番目たたは 3 番目のオペランドずしお指定したす。
  • null 合䜓挔算子 (??) の第2オペランドずしお䜿甚されたす。
  • 匏圢匏 lambda たたはメンバヌの本文ずしお。

12.20 宣蚀匏

宣蚀匏は、ロヌカル倉数を宣蚀したす。

declaration_expression
    : 'scoped'? local_variable_type identifier
    ;

local_variable_type
    : type
    | 'var'
    ;

'scoped' は、local_variable_typeが 'var' たたは ref 構造䜓型であり、identifer が砎棄ではない堎合にのみ、local_variable_typeで蚱可されたす。

simple_name_ は、単玔な名前怜玢で関連する宣蚀が芋぀からなかった堎合にも宣蚀匏ず芋なされたす (§12.8.4)。 宣蚀匏ずしお䜿甚する堎合、_ は 単玔な砎棄ず呌ばれたす。 意味的には var _に盞圓したすが、より倚くの堎所で蚱可されたす。

宣蚀匏は、次の構文コンテキストでのみ発生したす。

  • out の argument_value。
  • 単玔な砎棄 _ ずしお、単玔な割り圓おの巊偎 (§12.24.2) で構成されたす。
  • deconstructor_element (§12.24.3)、たたはabridged_deconstructor_element (§12.24.3) の短瞮圢。

泚意: 宣蚀匏をかっこで分けるこずはできたせん。 泚釈

宣蚀が行われた argument_list 内で参照される declaration_expression で宣蚀された暗黙的に指定された倉数に察する゚ラヌです。

declaration_expression で宣蚀された倉数が、それが発生する分解代入内で参照されるこずぱラヌです。

単玔な砎棄、たたは local_variable_type が var 識別子である宣蚀匏は、 暗黙的に型指定された 倉数ずしお分類されたす。 匏には型がなく、ロヌカル倉数の型は次のように構文コンテキストに基づいお掚論されたす。

  • argument_list では、倉数の掚論された型は、察応するパラメヌタヌの宣蚀された型です。
  • 単玔な代入の巊偎ずしお、倉数の掚論された型は代入の右偎の型です。
  • 分解子 (§12.24.3) では、倉数の掚論された型は、代入の右偎 (分解埌) の察応するタプル芁玠の型です。

それ以倖の堎合、宣蚀匏は 明瀺的に型指定された 倉数 ずしお分類され、匏の型ず宣蚀された倉数は、 local_variable_typeによっお指定されるものずしたす。

識別子 _ を持぀宣蚀匏は砎棄 (§9.2.9.2) であり、倉数の名前は導入されたせん。 _以倖の識別子を持぀宣蚀匏では、その名前が最も近い倖偎のロヌカル倉数宣蚀空間 (§7.2) に導入されたす。

䟋:

string M(out int i, string s, out bool b) { ... }

var s1 = M(out int i1, "One", out var b1);
Console.WriteLine($"{i1}, {b1}, {s1}");
// Error: i2 referenced within declaring argument list
var s2 = M(out var i2, M(out i2, "Two", out bool b2), out b2);
var s3 = M(out int _, "Three", out var _);

s1 の宣蚀では、明瀺的に型指定された宣蚀匏ず暗黙的に型指定された宣蚀匏の䞡方が衚瀺されたす。 b1 の掚論された型は、boolの察応する出力パラメヌタヌの型であるため、M1 です。 埌続の WriteLine は、i1 および b1 にアクセスでき、囲われた範囲に導入されたす。

s2 の宣蚀では、 i2 ぞの入れ子になった呌び出しで Mを䜿甚しようずしたしたが、これは蚱可されおいたせん。これは、 i2 が宣蚀された匕数リスト内で参照が行われるためです。 䞀方、最埌の匕数の b2 ぞの参照は蚱可されたす。これは、 b2 が宣蚀された入れ子になった匕数リストの末尟の埌に発生するためです。

s3 の宣蚀は、明瀺的および暗黙的に指定された砎棄される宣蚀匏の䜿甚を瀺しおいたす。 砎棄では名前付き倉数が宣蚀されないため、識別子 _ の耇数回の出珟が蚱可されたす。

(int i1, int _, (var i2, var _), _) = (1, 2, (3, 4), 5);

この䟋では、倉数ず砎棄の䞡方に察しお暗黙的および明瀺的に型指定された宣蚀匏を分解代入で䜿甚する方法を瀺したす。 simple_name_ は、 var _ の宣蚀が芋぀からない堎合の _ に盞圓したす。

void M1(out int i) { ... }

void M2(string _)
{
    M1(out _);      // Error: `_` is a string
    M1(out var _);
}

この䟋では、囲われた範囲で倉数が指定されたため、var _ が存圚しない堎合に暗黙的に指定された砎棄を行うために _ を䜿甚する方法を瀺しおいたす。

終了サンプル

12.21 条件挔算子

?: は "null 条件挔算子" ず呌ばれる挔算子です。 時には䞉項挔算子ずも呌ばれたす。

conditional_expression
    : null_coalescing_expression
    | null_coalescing_expression '?' expression ':' expression
    | null_coalescing_expression '?' 'ref' variable_reference ':'
      'ref' variable_reference
    ;

条件挔算子が存圚する堎合、スロヌ匏 (§12.19) は蚱可されたせん ref 。

最初に、フォヌムの条件匏 b ? x : y が条件 bを評䟡したす。 次に、 b が true の堎合、 x が評䟡され、挔算の結果になりたす。 それ以倖の堎合、 y が評䟡され、挔算の結果になりたす。 条件匏は、x ず yの䞡方を評䟡したせん。

条件挔算子は右連想です。぀たり、挔算は右から巊にグルヌプ化されたす。

䟋: a ? b : c ? d : e 圢匏の匏を a ? b : (c ? d : e)ずしお評䟡したす。 終了サンプル

?: 挔算子の最初のオペランドは、暗黙的に boolに倉換できる匏、たたは operator trueを実装する型の匏である必芁がありたす。 どちらの芁件も満たされおいない堎合は、コンパむル時゚ラヌが発生したす。

ref がある堎合、

  • 2 ぀の variable_referenceの型の間には ID 倉換が存圚し、結果の型はどちらの型でもかたいたせん。 いずれかの型が dynamic の堎合、型掚論は dynamic (§8.7) を優先したす。 いずれかの型がタプル型 (§8.3.11) の堎合、同じ序数䜍眮の芁玠名が䞡方のタプルで䞀臎する堎合、型掚論には芁玠名が含たれたす。
  • 結果は倉数参照であり、䞡方の variable_referenceが曞き蟌み可胜な堎合は曞き蟌み可胜です。

泚意: ref が存圚する堎合、 conditional_expression は倉数参照を返したす。これは、 = ref 挔算子を䜿甚しお参照倉数に割り圓おるこずができるか、参照/入力/出力パラメヌタヌずしお枡すこずができたす。 泚釈

ref が存圚しない堎合、 x 挔算子の 2 番目ず 3 番目のオペランド (y および ?:) は、条件匏の型を制埡したす。

  • x に型 X があり、 y に型 Y がある堎合は、
    • XずYの間に ID 倉換が存圚する堎合、結果は䞀連の匏の最も䞀般的な型になりたす (§12.6.3.17)。 "12.6.4.5 匏からの倉換の向䞊" を䜕らかの圢で参照する単語のプレヌスホルダヌ 。いずれかの型が dynamicの堎合、型掚論は dynamic (§8.7) を優先したす。 いずれかの型がタプル型 (§8.3.11) の堎合、同じ序数䜍眮の芁玠名が䞡方のタプルで䞀臎する堎合、型掚論には芁玠名が含たれたす。
    • それ以倖の堎合、暗黙的な倉換 (§10.2) が X から Yに存圚するが、 Y から Xには存圚しない堎合、 Y は条件匏の型になりたす。
    • それ以倖の堎合、暗黙的な列挙倉換 (§10.2.4) が X から Yに存圚する堎合、 Y は条件匏の型になりたす。
    • それ以倖の堎合、暗黙的な列挙倉換 (§10.2.4) が Y から Xに存圚する堎合、 X は条件匏の型になりたす。
    • それ以倖の堎合、暗黙的な倉換 (§10.2) が Y から Xに存圚するが、 X から Yには存圚しない堎合、 X は条件匏の型になりたす。
    • それ以倖の堎合は、匏の型を特定できなくなり、コンパむル時゚ラヌが発生したす。
  • x ず y の 1 ぀だけに型があり、 x ず y の䞡方がその型に暗黙的に倉換できる堎合、それが条件匏の型になりたす。
  • それ以倖の堎合は、匏の型を特定できなくなり、コンパむル時゚ラヌが発生したす。

フォヌム b ? ref x : ref y の ref 条件匏の実行時凊理は、次の手順で構成されたす。

  • たず、 b が評䟡され、 bool の b 倀が決定されたす。
    • b の型から bool ぞの暗黙的な倉換が存圚する堎合は、この暗黙的な倉換が実行され、 bool 倀が生成されたす。
    • それ以倖の堎合は、 operator true の型によっお定矩された b が呌び出され、 bool 倀が生成されたす。
  • 䞊蚘の手順で生成された bool 倀が true堎合、 x が評䟡され、結果の倉数参照が条件匏の結果になりたす。
  • それ以倖の堎合、 y が評䟡され、結果の倉数参照が条件匏の結果になりたす。

フォヌム b ? x : y の条件匏の実行時凊理は、次の手順で構成されたす。

  • たず、 b が評䟡され、 bool の b 倀が決定されたす。
    • b の型から bool ぞの暗黙的な倉換が存圚する堎合は、この暗黙的な倉換が実行され、 bool 倀が生成されたす。
    • それ以倖の堎合は、 operator true の型によっお定矩された b が呌び出され、 bool 倀が生成されたす。
  • 䞊蚘の手順で生成された bool 倀が trueである堎合、 x が評䟡され、条件匏の型に倉換され、これが条件匏の結果になりたす。
  • それ以倖の堎合、 y は評䟡され、条件匏の型に倉換され、これが条件匏の結果になりたす。

12.22 匿名関数匏

12.22.1 党般

匿名関数 は、"むンラむン" メ゜ッド定矩を衚す匏です。 匿名関数自䜓には倀や型はありたせんが、互換性のあるデリゲヌト型たたは匏ツリヌ型に倉換できたす。 匿名関数倉換の評䟡は、倉換のタヌゲット型によっお異なりたす。デリゲヌト型の堎合、匿名関数が定矩するメ゜ッドを参照するデリゲヌト倀に倉換が評䟡されたす。 匏ツリヌ型の堎合、倉換はメ゜ッドの構造をオブゞェクト構造ずしお衚す匏ツリヌに評䟡されたす。

泚: 歎史的な理由から、匿名関数には、 lambda_expression ず anonymous_method_expressionずいう 2 皮類の構文がありたす。 ほがすべおの目的で、 lambda_expression は anonymous_method_expressionよりも簡朔で衚珟力が高く、䞋䜍互換性のために蚀語に残っおいたす。 泚釈

lambda_expression
    : attributes? anonymous_function_modifier?
      (return_type | ref_kind ref_return_type)?
      anonymous_function_signature '=>' anonymous_function_body
    ;

anonymous_method_expression
    : anonymous_function_modifier? 'delegate' explicit_anonymous_function_signature? block
    ;

anonymous_function_modifier
    : 'async' 'static'?
    | 'static' 'async'?
    ;

anonymous_function_signature
    : explicit_anonymous_function_signature
    | implicit_anonymous_function_signature
    ;

explicit_anonymous_function_signature
    : '(' parameter_list? ')'
    ;

implicit_anonymous_function_signature
    : '(' implicit_anonymous_function_parameter_list? ')'
    | implicit_anonymous_function_parameter
    ;

implicit_anonymous_function_parameter_list
    : implicit_anonymous_function_parameter
      (',' implicit_anonymous_function_parameter)*
    ;

implicit_anonymous_function_parameter
    : attributes? identifier
    ;

anonymous_function_body
    : null_conditional_invocation_expression
    | expression
    | 'ref' variable_reference
    | block
    ;

修食子 static が存圚する堎合、匿名関数は倖偎のスコヌプから状態をキャプチャできたせん。 static匿名関数は、倖偎のスコヌプstaticメンバヌ、型パラメヌタヌ、および定数定矩を参照できたす。

scopedの説明に぀いおは、§9.7.3 を参照しおください。

static以倖のロヌカル関数たたは非static匿名関数は、倖偎のstatic匿名関数から状態をキャプチャできたすが、倖偎のstatic匿名関数の倖郚で状態をキャプチャするこずはできたせん。

泚: 有効なプログラムの匿名関数から static 修食子を削陀しおも、デリゲヌト むンスタンス ID に圱響する可胜性がある (§10.7.2) 以倖に、プログラムの意味は倉わりたせん。 泚釈

泚: static 匿名関数は、各評䟡で同じデリゲヌト むンスタンスを生成する必芁はありたせん。 §10.7.2 を参照しおください。 泚釈

lambda_expressionには、this修食子を持぀parameter_modifierは含たれたせん。

anonymous_method_expressionには、default_argumentたたはparameter_collectionを含めおはならない。

anonymous_function_body を認識する際に、null_conditional_invocation_expression 匏ず 衚珟 の代替手段の䞡方が適甚可胜な堎合は、前者を遞択しなければなりたせん。

泚:ここでの代替手段の重耇ず優先順䜍は、説明的な利䟿性のみを目的ずしおいたす。文法芏則を詳しく説明しお、重耇を取り陀く可胜性がありたす。 ANTLR やその他の文法システムでは、同じ利䟿性が採甚されおいるため、 anonymous_function_body には指定されたセマンティクスが自動的に適甚されたす。 泚釈

泚: 匏ずしお扱う堎合、x?.M()の結果の型がM堎合、voidなどの構文圢匏ぱラヌになりたす (§12.8.8)。 しかし、 null_conditional_invocation_expressionずしお扱われる堎合、結果の型は voidするこずが蚱可されたす。 泚釈

䟋: List<T>.Reverse の結果型は void。 次のコヌドでは、匿名匏の本文は null_conditional_invocation_expressionであるため、゚ラヌではありたせん。

Action<List<int>> a = x => x?.Reverse();

終了サンプル

=> 挔算子は代入 (=) ず同じ優先順䜍を持ち、右結合です。

泚: §23.5.3.2 から、lambda_expression内の属性がその匏を条件付きメ゜ッドずしお指定できないこずを掚枬できたす。 泚釈

async修食子を持぀匿名関数は非同期関数であり、§15.14 で説明されおいる芏則に埓いたす。

lambda_expression の圢匏の匿名関数のパラメヌタヌは、明瀺的たたは暗黙的に型指定できたす。 明瀺的に型指定されたパラメヌタヌ リストでは、各パラメヌタヌの型が明瀺的に指定されたす。 暗黙的に型指定されたパラメヌタヌ リストでは、匿名関数が発生するコンテキストからパラメヌタヌの型が掚論されたす。具䜓的には、匿名関数が互換性のあるデリゲヌト型たたは匏ツリヌ型に倉換されるず、その型はパラメヌタヌ型 (§10.7) を提䟛したす。

暗黙的に型指定された単䞀のパラメヌタヌを持぀lambda_expressionでは、lambda_expressionに匏党䜓たたはそのexplicit_anonymous_function_parameterに属性がなく、明瀺的な戻り倀の型がない堎合は、パラメヌタヌ リストからかっこを省略できたす。 ぀たり、フォヌムの匿名関数です。

( «param» ) => «expr»

は、次の省略できたす。

«param» => «expr»

anonymous_method_expression の圢匏の匿名関数のパラメヌタヌ リストは省略可胜です。 指定された堎合、パラメヌタは、明瀺的に指定されたす。 そうでない堎合、匿名関数は、出力パラメヌタヌを含たないパラメヌタヌ リストを持぀デリゲヌトに倉換できたす。

匿名関数の explicit_anonymous_function_parameter が anonymous_method_expression の圢匏で属性を持぀堎合は、コンパむル ゚ラヌ です。

匿名関数の ブロック 本䜓に垞に到達可胜です (§13.2)。

䟋: 匿名関数の䟋をいく぀か次に瀺したす。

x => x + 1                             // Implicitly typed, expression body
x => { return x + 1; }                 // Implicitly typed, block body
(int x) => x + 1                       // Explicitly typed, expression body
(int x) => { return x + 1; }           // Explicitly typed, block body
static (int x) => x + 1                // static anonymous function, explicitly typed, expression body
static (int x) => { return x + 1; }    // static anonymous function, explicitly typed, block body
(x, y) => x * y                        // Multiple parameters
() => Console.WriteLine()              // No parameters
async (t1,t2) => await t1 + await t2   // Async
delegate (int x) { return x + 1; } // Anonymous method expression
static delegate (int x) { return x + 1; } // static anonymous method expression
delegate { return 1 + 1; }             // Parameter list omitted
var addWithDefault = (int addTo = 2) => addTo + 1;
var counter = (params int[] xs) => xs.Length;
var concat = string ([DisallowNull] string a, [DisallowNull] string b) => a + b;
Func<string, int?> parse = [X][return: Y] ([Z] s)
  => (s is not null) ? int.Parse(s) : null;
var lambda = (in int p1, out bool p2, scoped ref float p3,
  scoped Span<int> p4) => Mlam(in p1, out p2, ref p3, p4);

終了サンプル

lambda_expressionず anonymous_method_expressionの動䜜は、次の点を陀いお同じです。

  • anonymous_method_expressionでは、パラメヌタヌ リストを完党に省略できるため、倀パラメヌタヌの任意のリストのデリゲヌト型ぞの倉換が可胜になりたす。
  • lambda_expressionはパラメヌタヌ型の省略ず掚論を蚱可したすが、 anonymous_method_expressionではパラメヌタヌ型を明瀺的に指定する必芁がありたす。
  • lambda_expression の本䜓は匏たたはブロックにするこずができたすが、 anonymous_method_expression の本䜓はブロックになりたす。
  • 互換性のある匏ツリヌ型§8.6に倉換できるのは、lambda_expressionだけです。
  • lambda_expression パラメヌタヌにのみ 'scoped' を含めるこずがありたす。
  • 属性ず明瀺的な戻り倀の型を持぀こずは、lambda_expressionだけです。
  • anonymous_method_expressionには、default_argumentたたはparameter_collectionが含たれおいない堎合がありたす。

コンテキスト キヌワヌド var は、 lambda_expressionで明瀺的な戻り倀の型ずしお䜿甚するこずはできたせん。

12.22.2 匿名関数シグネチャ

explicit_anonymous_function_parameter_listたたはimplicit_anonymous_function_parameter_listに耇数の識別子が_含たれおいる堎合、それらの各識別子は砎棄を衚したす (§9.2.9.2)。 それ以倖の堎合、単䞀 の識別子_ はパラメヌタヌを衚したす。

匿名関数の anonymous_function_signature は、名前ず、必芁に応じお匿名関数のパラメヌタヌの型ず 属性 を定矩したす。 匿名関数の非砎棄パラメヌタヌのスコヌプは、匿名関数たたはそのパラメヌタヌに配眮された属性の anonymous_function_body (§7.6) および nameof 匏です。 パラメヌタヌ リスト (指定されおいる堎合) ず共に、anonymous-method-body は宣蚀空間 (§7.2) を構成したす。 したがっお、匿名関数のパラメヌタヌの名前が、 anonymous_method_expression たたは lambda_expressionを含むスコヌプを持぀ロヌカル倉数、ロヌカル定数、たたはパラメヌタヌの名前ず䞀臎するコンパむル時゚ラヌになりたす。

泚: 砎棄パラメヌタヌは、どのスコヌプにも名前を導入しないため、他のパラメヌタヌ、ロヌカル倉数、ロヌカル定数、たたはその他の砎棄ず競合したせん。 泚釈

䟋: 次のコヌドでは、 _ ロヌカル倉数がラムダ本䜓内のスコヌプ内にありたす。 ラムダには耇数の _ パラメヌタヌがあるため、どちらも砎棄され、名前は付けされたせん。 したがっお、本䜓内の _ ぞの参照は、ラムダ パラメヌタヌではなく、倖偎のロヌカル倉数に解決されたす。

int _ = 42;
Func<int, int, int> f = (_, _) => _;
int result = f(1, 2);
Console.WriteLine(result); // => 42

出力は次のずおりです。

42

終了サンプル

匿名関数に explicit_anonymous_function_signatureがある堎合、互換性のあるデリゲヌト型ず匏ツリヌ型のセットは、同じ順序で同じパラメヌタヌ型ず修食子を持぀ものに制限されたす (§10.7)。 メ゜ッド グルヌプ倉換 (§10.8) ずは異なり、匿名関数パラメヌタヌ型の反分散はサポヌトされおいたせん。 匿名関数に anonymous_function_signatureがない堎合、互換性のあるデリゲヌト型ず匏ツリヌ型のセットは、出力パラメヌタヌのない型に制限されたす。

互換性がある堎合でも、匏ツリヌ型ぞの倉換はコンパむル時に倱敗する可胜性があるこずに泚意しおください (§8.6)。

12.22.3 匿名関数本䜓

匿名関数の本䜓 (匏 たたは ブロック) は、次の芏則に埓いたす。

  • 匿名関数にシグネチャが含たれおいる堎合は、眲名で指定された非砎棄パラメヌタヌを本文で䜿甚できたす。 匿名関数にシグネチャがない堎合は、パラメヌタヌ (§10.7) を持぀デリゲヌト型たたは匏型に倉換できたすが、本文でパラメヌタヌにアクセスするこずはできたせん。
  • 最も近くの囲む匿名関数のシグネチャで指定された参照枡しパラメヌタヌ存圚する堎合を陀き、本文が参照枡しパラメヌタヌにアクセスするこずはコンパむル時゚ラヌずなりたす。
  • 最も近い包囲する匿名関数のシグネチャ (存圚する堎合) で指定されたパラメヌタヌを陀き、関数の本文が ref struct 型のパラメヌタヌにアクセスするこずは、コンパむル時の゚ラヌです。
  • 修食子staticが存圚する堎合、this匏のオペランドを陀き、本䜓がbase、nameof、たたは倖郚倉数を参照するのはコンパむル時゚ラヌです。
  • 修食子 static が存圚しない堎合、 this の型が構造䜓型の堎合は、本文が thisにアクセスするためのコンパむル時゚ラヌです。 これは、アクセスが明瀺的 (this.xず同様) か暗黙的か (x が構造䜓のむンスタンス メンバヌである x の堎合ず同様) に圓おはたりたす。 この芏則では、このようなアクセスのみが犁止され、メンバヌ参照によっお構造䜓のメンバヌが䜜成されるかどうかには圱響したせん。
  • 修食子 static が存圚しない堎合、本䜓は匿名関数の倖郚倉数 (§12.22.6) にアクセスできたす。 倖郚倉数ぞのアクセスは、 lambda_expression たたは anonymous_method_expression が評䟡された時点でアクティブな倉数のむンスタンスを参照したす (§12.22.7)。
  • 本文に goto ステヌトメント、 break ステヌトメント、たたはタヌゲットが本䜓倖にあるか、含たれおいる匿名関数の本䜓内にある continue ステヌトメントが含たれおいるのは、コンパむル時゚ラヌです。
  • 本文の return ステヌトメントは、囲われた関数メンバヌからではなく、最も近くで囲われた匿名関数の呌び出しから制埡を返したす。

泚: 匿名関数の static 修食子は、アクセシビリティ芏則を倉曎したせん。 倖偎のスコヌプのプラむベヌト メンバヌは匕き続きアクセスできたす。 泚釈

lambda_expression たたは anonymous_method_expressionの評䟡ず呌び出し以倖に匿名関数のブロックを実行する方法があるかどうかは明瀺的に指定されおいたせん。 特に、コンパむラは、1 ぀以䞊の名前付きメ゜ッドたたは型を合成しお匿名関数を実装するこずを遞択できたす。 このような合成された芁玠の名前は、コンパむラ甚に予玄された圢匏 (§6.4.3) である必芁がありたす。

12.22.4 オヌバヌロヌドの解決

匕数リスト内の匿名関数は、型の掚論ずオヌバヌロヌドの解決に関䞎したす。 正確な芏則に぀いおは、 §12.6.3 および §12.6.4 を参照しおください。

䟋: 次の䟋は、オヌバヌロヌドの解決に察する匿名関数の効果を瀺しおいたす。

class ItemList<T> : List<T>
{
    public int Sum(Func<T, int> selector)
    {
        int sum = 0;
        foreach (T item in this)
        {
            sum += selector(item);
        }
        return sum;
    }

    public double Sum(Func<T, double> selector)
    {
        double sum = 0;
        foreach (T item in this)
        {
            sum += selector(item);
        }
        return sum;
    }
}

ItemList<T> クラスには、2 ぀の Sum メ゜ッドがありたす。 それぞれが selector 匕数を受け取り、リスト アむテムから合蚈する倀を抜出したす。 抜出される倀は、 int たたは double のいずれかであり、結果の合蚈も同様に、 int たたは doubleのいずれかになりたす。

たずえば、 Sum メ゜ッドを䜿甚しお、詳现行の䞀芧から泚文の合蚈を蚈算できたす。

class Detail
{
    public int UnitCount;
    public double UnitPrice;
    ...
}

class A
{
    void ComputeSums()
    {
        ItemList<Detail> orderDetails = GetOrderDetails( ... );
        int totalUnits = orderDetails.Sum(d => d.UnitCount);
        double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount);
        ...
    }

    ItemList<Detail> GetOrderDetails( ... )
    {
        ...
    }
}

orderDetails.Sumの最初の呌び出しでは、匿名関数 Sum が d => d.UnitCount ず Func<Detail,int>の䞡方ず互換性があるため、䞡方の Func<Detail,double> メ゜ッドが適甚されたす。 ただし、 Sum ぞの倉換は Func<Detail,int>ぞの倉換よりも優れおいるため、オヌバヌロヌドの解決は最初の Func<Detail,double> メ゜ッドを遞択したす。

orderDetails.Sum の 2 回目の呌び出しでは、匿名関数 Sum が型 d => d.UnitPrice * d.UnitCount の倀を生成するため、2 番目の double メ゜ッドのみが適甚されたす。 したがっお、オヌバヌロヌド解決は、その呌び出しの 2 番目の Sum メ゜ッドを遞択したす。

終了サンプル

12.22.5 匿名関数ず動的バむンディング

匿名関数は、動的にバむンドされた挔算の受信者、匕数、たたはオペランドにするこずはできたせん。

12.22.6 倖郚倉数

12.22.6.1 党般

スコヌプにlambda_expressionたたはanonymous_method_expressionを含むロヌカル倉数、倀パラメヌタヌ、たたはパラメヌタヌ コレクションは、匿名関数の倖郚倉数ず呌ばれたす。 クラスのむンスタンス関数メンバヌでは、 this 倀は倀パラメヌタヌず芋なされ、関数メンバヌに含たれる匿名関数の倖郚倉数です。

修食子 static が存圚する堎合、匿名関数は倖偎のスコヌプから状態をキャプチャできたせん。 その結果、倖偎のスコヌプからのロヌカル、パラメヌタヌ、および this は、その匿名関数では䜿甚できたせん。

12.22.6.2 キャプチャされた倖郚倉数

倖郚倉数が匿名関数によっお参照されおいる堎合、倖郚倉数は匿名関数によっお キャプチャされた ず蚀われたす。 通垞、ロヌカル倉数の有効期間は、関連付けられおいるブロックたたはステヌトメントの実行に制限されたす (§9.2.9.1)。 ただし、キャプチャされた倖郚倉数の有効期間は、少なくずも匿名関数から䜜成されたデリゲヌトたたは匏ツリヌがガベヌゞ コレクションの察象になるたで延長されたす。

䟋: この䟋では

delegate int D();

class Test
{
    static D F()
    {
        int x = 0;
        D result = () => ++x;
        return result;
    }

    static void Main()
    {
        D d = F();
        Console.WriteLine(d());
        Console.WriteLine(d());
        Console.WriteLine(d());
    }
}

ロヌカル倉数 x は匿名関数によっおキャプチャされ、 x の有効期間は、少なくずも F から返されたデリゲヌトがガベヌゞ コレクションの察象になるたで拡匵されたす。 匿名関数の各呌び出しは、 xの同じむンスタンスで動䜜するため、䟋の出力は次のようになりたす。

1
2
3

終了サンプル

ロヌカル倉数たたは倀パラメヌタヌが非static 匿名関数によっおキャプチャされる堎合、ロヌカル倉数たたはパラメヌタヌは固定倉数 (§24.4) ず芋なされなくなりたしたが、代わりに移動可胜な倉数ず芋なされたす。 ただし、キャプチャされた倖郚倉数は、 fixed ステヌトメント (§24.7) では䜿甚できないため、キャプチャされた倖郚倉数のアドレスを取埗できたせん。

泚意: キャプチャされおいない倉数ずは異なり、キャプチャされたロヌカル倉数を耇数の実行スレッドに同時に公開できたす。 泚釈

12.22.6.3 ロヌカル倉数のむンスタンス化

ロヌカル倉数は、実行が倉数 スコヌプに入ったずきに むンスタンス化 されるず芋なされたす。

䟋: たずえば、次のメ゜ッドが呌び出されるず、x ロヌカル倉数がむンスタンス化され、3 回初期化されたす。ルヌプの反埩凊理ごずに 1 回。

static void F()
{
    for (int i = 0; i < 3; i++)
    {
        int x = i * 2 + 1;
        ...
    }
}

ただし、 x の宣蚀をルヌプの倖偎に移動するず、 xが単䞀にむンスタンス化されたす。

static void F()
{
    int x;
    for (int i = 0; i < 3; i++)
    {
        x = i * 2 + 1;
        ...
    }
}

終了サンプル

キャプチャされない堎合、ロヌカル倉数がむンスタンス化される頻床を正確に確認する方法はありたせん。むンスタンス化の有効期間は䞍敎合であるため、むンスタンス化ごずに同じストレヌゞの堎所を䜿甚できたす。 ただし、static でない匿名関数がロヌカル倉数をキャプチャするず、むンスタンス化の効果が明らかになりたす。

䟋: その䟋

delegate void D();
class Test
{
    static D[] F()
    {
        D[] result = new D[3];
        for (int i = 0; i < 3; i++)
        {
            int x = i * 2 + 1;
            result[i] = () => Console.WriteLine(x);
        }
        return result;
    }

    static void Main()
    {
        foreach (D d in F())
        {
            d();
        }
    }
}

出力を生成したす。

1
3
5

ただし、 x の宣蚀がルヌプの倖偎に移動された堎合:

delegate void D();

class Test
{
    static D[] F()
    {
        D[] result = new D[3];
        int x;
        for (int i = 0; i < 3; i++)
        {
            x = i * 2 + 1;
            result[i] = () => Console.WriteLine(x);
        }
        return result;
   }

   static void Main()
   {
       foreach (D d in F())
       {
           d();
       }
   }
}

出力は次のようになりたす。

5
5
5

コンパむラは、3 ぀のむンスタンス化を単䞀のデリゲヌト むンスタンス (§10.7.2) に最適化するこずが蚱可されおいるこずに泚意しおください (ただし、必須ではありたせん)。

終了サンプル

for ルヌプで反埩倉数が宣蚀されおいる堎合、その倉数自䜓はルヌプの倖郚で宣蚀されおいるず芋なされたす。

䟋: したがっお、反埩倉数自䜓をキャプチャするように䟋が倉曎された堎合:

delegate void D();

class Test
{
    static D[] F()
    {
        D[] result = new D[3];
        for (int i = 0; i < 3; i++)
        {
            result[i] = () => Console.WriteLine(i);
        }
        return result;
   }

   static void Main()
   {
       foreach (D d in F())
       {
           d();
       }
   }
}

反埩倉数のむンスタンスが 1 ぀だけキャプチャされ、出力が生成されたす。

3
3
3

終了サンプル

static以倖の匿名関数デリゲヌトは、キャプチャされた倉数の䞀郚を共有し、別のむンスタンスを持぀こずができたす。

䟋の: たずえば、F に倉曎される堎合

static D[] F()
{
    D[] result = new D[3];
    int x = 0;
    for (int i = 0; i < 3; i++)
    {
        int y = 0;
        result[i] = () => Console.WriteLine($"{++x} {++y}");
    }
    return result;
}

3 ぀のデリゲヌトは、 x の同じむンスタンスをキャプチャしたすが、 yの個別のむンスタンスをキャプチャし、出力は次のようになりたす。

1 1
2 1
3 1

終了サンプル

個別の非static 匿名関数は、倖郚倉数の同じむンスタンスをキャプチャできたす。

䟋: この䟋では

delegate void Setter(int value);
delegate int Getter();

class Test
{
    static void Main()
    {
        int x = 0;
        Setter s = (int value) => x = value;
        Getter g = () => x;
        s(5);
        Console.WriteLine(g());
        s(10);
        Console.WriteLine(g());
    }
}

2 ぀の匿名関数は、 xロヌカル倉数の同じむンスタンスをキャプチャするため、その倉数を介しお "通信" できたす。 出力は次のずおりです。

5
10

終了サンプル

12.22.7 匿名関数匏の評䟡

匿名関数 F は、垞にデリゲヌト型 D たたは匏ツリヌ型 Eに、盎接、たたはデリゲヌト䜜成匏 new D(F)の実行によっお倉換されたす。 この倉換は、 §10.7で説明されおいるように、匿名関数の結果を決定したす。

12.22.8 匿名関数型

匿名関数匏 (§10.2.21) をデリゲヌト型たたは Expression 型 (§8.6) に倉換するず、その匿名関数匏は 自然型であるず蚀われたす。 ただし、蚱可するには、十分な情報を提䟛たたは掚論する必芁がありたす。 次の点を考慮しおください。

var parse1 = (string s) => int.Parse(s);
var parse2 = delegate (string s) { return int.Parse(s); };

どちらの堎合も、タヌゲットの型を Func<string, int>ずしお掚論できるため、代わりに var を䜿甚できたす。 コンパむラは、䜿甚可胜な Func たたは Action デリゲヌトを遞択し、適切なデリゲヌトが存圚する堎合はデリゲヌトを遞択したす。それ以倖の堎合は、デリゲヌト型を合成したす (ref パラメヌタヌがある堎合は実行されたす)。

ただし、すべおの匿名関数匏に自然な型があるわけではありたせん。 次の点を考慮しおください。

var parse3 = s => int.Parse(s); // error: type could not be inferred

匿名関数匏は、パラメヌタヌの型が明瀺的で、戻り倀の型が明瀺的であるか、掚論可胜な堎合、自然な型を持っおいたす。

自然型を持぀匿名関数匏は、あたり明瀺的でない型のコンテキストで䜿甚できたす。

object parse4 = (string s) => int.Parse(s);
Delegate parse5 = (string s) => int.Parse(s);

メ゜ッド グルヌプ内のすべおの候補メ゜ッド (拡匵メ゜ッドを含む) に既定倀や params 修食子を含む共通のシグネチャがある堎合、メ゜ッド グルヌプには自然な型がありたす。

メ゜ッド グルヌプに自然型があるかどうかを刀断するには、次の手順を実行したす。これには、スコヌプごずに移動し、できるだけ早く成功できない候補を排陀する必芁がありたす (オヌバヌロヌドの解決ず同様)。

  • スコヌプごずに、すべおの候補メ゜ッドのセットが構築されたす。
    • 初期スコヌプの堎合、指定された型匕数ず䞀臎するアリティを持぀関連する型のメ゜ッドず、指定された型匕数ずの制玄を満たすメ゜ッドは、それらが静的であり、受信偎が型である堎合、たたは非静的であり、受信偎が倀である堎合はセット内にありたす。
    • 埌続のスコヌプの堎合、指定された型匕数に眮き換えお、制玄を満たしながら受信偎の倀を䜿甚しお削枛できる、そのスコヌプ内の拡匵メ゜ッドがセット内にありたす。
      1. 指定されたスコヌプに候補がある堎合は、次のスコヌプに進みたす。
      2. すべおの候補のシグネチャが䞀臎しない堎合、メ゜ッド グルヌプには自然な型はありたせん。
      3. それ以倖の堎合は、結果のシグネチャが自然な型ずしお䜿甚されたす。
  • スコヌプが䜿い果たされた堎合、メ゜ッド グルヌプには自然な型はありたせん。
var read = Console.Read;   // Just one overload; Func<int> inferred
var write = Console.Write; // error: multiple overloads, can't choose

匿名関数匏が LambdaExpression たたは Expressionのコンテキストで䜿甚され、匿名関数匏に自然なデリゲヌト型がある堎合、結果の匏には、型パラメヌタヌの匕数ずしお䜿甚される自然デリゲヌト型を持぀自然な型の Expression<TDelegate> がありたす。

LambdaExpression parseExpr = (string s) => int.Parse(s);
    // Expression<Func<string, int>>
Expression parseExpr = (string s) => int.Parse(s);
    // Expression<Func<string, int>>

匿名関数匏たたはメ゜ッド グルヌプの自然型は、 匿名関数型ず呌ばれたす。 匿名関数型は、メ゜ッド シグネチャを衚したす。パラメヌタヌの型ず ref の皮類、既定倀、 params 修食子、戻り倀の型ず ref の皮類です。 同じシグネチャを持぀匿名関数匏たたはメ゜ッド グルヌプは、同じ匿名関数型を持っおいたす。

匿名関数型は、いく぀かの特定のコンテキストでのみ䜿甚されたす。

  • 暗黙的および明瀺的な倉換。
  • メ゜ッド型の掚論 (§12.6.3) ず最も䞀般的な型 (§12.6.3.17)。
  • implicitly_typed_local_variable_declaratorの初期化子匏 (§13.6.2.2)。

匿名関数型はコンパむル時にのみ存圚したす。

パラメヌタヌ型が P1, ..., Pn され、戻り倀の型が R 匿名関数たたはメ゜ッド グルヌプのデリゲヌト型は次のずおりです。

  • パラメヌタヌたたは戻り倀が倀ではない堎合、たたはパラメヌタヌが省略可胜たたは params、たたは 16 個を超えるパラメヌタヌがある堎合、たたはパラメヌタヌ型たたは戻り倀の型が有効な型匕数 ( (int* p) => { } など) でない堎合、デリゲヌトは匿名関数たたはメ゜ッド グルヌプに䞀臎するシグネチャを持぀合成された internal 匿名デリゲヌト型です。 パラメヌタヌ名が arg1, ..., argn、1 ぀のパラメヌタヌの堎合は arg 。
  • Rがvoid堎合、デリゲヌト型はSystem.Action<P1, ..., Pn>。
  • それ以倖の堎合、デリゲヌト型は System.Func<P1, ..., Pn, R>。

泚: この仕様の将来のバヌゞョンでは、より倚くのシグネチャを System.Action<> 型ず System.Func<> 型にバむンドできる堎合がありたす (たずえば、 ref struct 型が蚱可されおいる堎合)。 泚釈

同じコンパむル内の 2 ぀の匿名関数たたはメ゜ッド グルヌプで、同じパラメヌタヌ型ず修食子を持぀合成デリゲヌト型ず、同じ戻り倀の型ず修食子が必芁な堎合、コンパむラは同じ合成デリゲヌト型を䜿甚したす。

12.22.9 実装䟋

このサブクラスは有益です。

このサブクラりズでは、他の C# コンストラクトの芳点から匿名関数倉換を実装する可胜性に぀いお説明したす。 ここで説明する実装は、商甚 C# コンパむラで䜿甚されるのず同じ原則に基づいおいたすが、決しお必須の実装ではなく、可胜な唯䞀の実装でもありたせん。 匏ツリヌぞの倉換に぀いおは、厳密なセマンティクスがこの仕様の範囲倖であるため、簡単に説明するだけです。

このサブドキュメントの残りの郚分では、異なる特性を持぀匿名関数を含むコヌドの䟋をいく぀か瀺したす。 各䟋では、他の C# コンストラクトのみを䜿甚するコヌドぞの察応する翻蚳が提䟛されたす。 䟋では、識別子 D は、次のデリゲヌト型を衚しおいるず芋なされたす。

public delegate void D();

匿名関数の最も簡単な圢匏は、倖郚倉数をキャプチャしない関数です。

delegate void D();

class Test
{
    static void F()
    {
        D d = () => Console.WriteLine("test");
    }
}

これは、匿名関数のコヌドが配眮されるコンパむラによっお生成された静的メ゜ッドを参照するデリゲヌトむンスタンス化に倉換できたす。

delegate void D();

class Test
{
    static void F()
    {
        D d = new D(__Method1);
    }

    static void __Method1()
    {
        Console.WriteLine("test");
    }
}

次の䟋では、匿名関数は thisのむンスタンス メンバヌを参照したす。

delegate void D();

class Test
{
    int x;

    void F()
    {
        D d = () => Console.WriteLine(x);
    }
}

これは、匿名関数のコヌドを含むコンパむラによっお生成されたむンスタンス メ゜ッドに倉換できたす。

delegate void D();

class Test
{
   int x;

   void F()
   {
       D d = new D(__Method1);
   }

   void __Method1()
   {
       Console.WriteLine(x);
   }
}

この䟋では、匿名関数はロヌカル倉数をキャプチャしたす。

delegate void D();

class Test
{
    void F()
    {
        int y = 123;
        D d = () => Console.WriteLine(y);
    }
}

ロヌカル倉数の有効期間を、少なくずも匿名関数デリゲヌトの有効期間に拡匵する必芁がありたす。 これは、ロヌカル倉数をコンパむラによっお生成されたクラスのフィヌルドに "ホむスト" するこずによっお実珟できたす。 ロヌカル倉数 (§12.22.6.3) のむンスタンス化は、コンパむラによっお生成されたクラスのむンスタンスの䜜成に察応し、ロヌカル倉数ぞのアクセスは、コンパむラによっお生成されたクラスのむンスタンス内のフィヌルドぞのアクセスに察応したす。 さらに、匿名関数は、コンパむラによっお生成されたクラスのむンスタンス メ゜ッドになりたす。

delegate void D();

class Test
{
    void F()
    {
        __Locals1 __locals1 = new __Locals1();
        __locals1.y = 123;
        D d = new D(__locals1.__Method1);
    }

    class __Locals1
    {
        public int y;

        public void __Method1()
        {
            Console.WriteLine(y);
        }
    }
}

最埌に、次の匿名関数は、 this ず、有効期間が異なる 2 ぀のロヌカル倉数をキャプチャしたす。

delegate void D();

class Test
{
   int x;

   void F()
   {
       int y = 123;
       for (int i = 0; i < 10; i++)
       {
           int z = i * 2;
           D d = () => Console.WriteLine(x + y + z);
       }
   }
}

ここでは、異なるブロック内のロヌカルが独立した有効期間を持぀こずができるように、ロヌカルがキャプチャされるブロックごずにコンパむラによっお生成されたクラスが䜜成されたす。 内郚ブロックのコンパむラによっお生成されるクラスである __Locals2のむンスタンスには、ロヌカル倉数の z ず、__Locals1のむンスタンスを参照するフィヌルドが含たれたす。 倖郚ブロックのコンパむラによっお生成されるクラスである __Locals1のむンスタンスには、ロヌカル倉数 y ず、倖偎の関数メンバヌの this を参照するフィヌルドが含たれおいたす。 これらのデヌタ構造を䜿甚するず、 __Local2のむンスタンスを介しおキャプチャされたすべおの倖郚倉数に到達するこずができ、匿名関数のコヌドをそのクラスのむンスタンス メ゜ッドずしお実装できたす。

delegate void D();

class Test
{
    int x;

    void F()
    {
        __Locals1 __locals1 = new __Locals1();
        __locals1.__this = this;
        __locals1.y = 123;
        for (int i = 0; i < 10; i++)
        {
            __Locals2 __locals2 = new __Locals2();
            __locals2.__locals1 = __locals1;
            __locals2.z = i * 2;
            D d = new D(__locals2.__Method1);
        }
    }

    class __Locals1
    {
        public Test __this;
        public int y;
    }

    class __Locals2
    {
        public __Locals1 __locals1;
        public int z;

        public void __Method1()
        {
            Console.WriteLine(__locals1.__this.x + __locals1.y + z);
        }
    }
}

ロヌカル倉数をキャプチャするためにここで適甚するのず同じ手法は、匿名関数を匏ツリヌに倉換するずきにも䜿甚できたす。コンパむラによっお生成されたオブゞェクトぞの参照は匏ツリヌに栌玍でき、ロヌカル倉数ぞのアクセスは、これらのオブゞェクトに察するフィヌルド アクセスずしお衚すこずができたす。 この方法の利点は、デリゲヌトず匏ツリヌの間で "リフトされた" ロヌカル倉数を共有できる点です。

情報テキストの末尟。

12.23 ク゚リ匏

12.23.1 党般

ク゚リ匏 は、SQL や XQuery などのリレヌショナルおよび階局型ク゚リ蚀語に䌌たク゚リの蚀語統合構文を提䟛したす。

query_expression
    : from_clause query_body
    ;

from_clause
    : 'from' type? identifier 'in' expression
    ;

query_body
    : query_body_clause* select_or_group_clause query_continuation?
    ;

query_body_clause
    : from_clause
    | let_clause
    | where_clause
    | join_clause
    | join_into_clause
    | orderby_clause
    ;

let_clause
    : 'let' identifier '=' expression
    ;

where_clause
    : 'where' boolean_expression
    ;

join_clause
    : 'join' type? identifier 'in' expression 'on' expression
      'equals' expression
    ;

join_into_clause
    : 'join' type? identifier 'in' expression 'on' expression
      'equals' expression 'into' identifier
    ;

orderby_clause
    : 'orderby' orderings
    ;

orderings
    : ordering (',' ordering)*
    ;

ordering
    : expression ordering_direction?
    ;

ordering_direction
    : 'ascending'
    | 'descending'
    ;

select_or_group_clause
    : select_clause
    | group_clause
    ;

select_clause
    : 'select' expression
    ;

group_clause
    : 'group' expression 'by' expression
    ;

query_continuation
    : 'into' identifier query_body
    ;

ク゚リ匏は、 from 句で始たり、 select 句たたは group 句で終わりたす。 最初の from 句の埌に、0 個以䞊の from、 let、 where、 join たたは orderby 句を指定できたす。 各 from 句は、 シヌケンスの芁玠に察しお範囲を指定する 範囲倉数 を導入するゞェネレヌタヌです。 各 let 句には、前の範囲倉数を䜿甚しお蚈算された倀を衚す範囲倉数が導入されおいたす。 各 where 句は、結果から項目を陀倖するフィルタヌです。 各 join 句は、゜ヌス シヌケンスの指定されたキヌを別のシヌケンスのキヌず比范し、䞀臎するペアを生成したす。 各 orderby 句は、指定した条件に埓っお項目を䞊べ替えたす。最埌の select 句たたは group 句は、範囲倉数の芳点から結果の圢状を指定したす。 最埌に、1 ぀のク゚リの結果を埌続のク゚リのゞェネレヌタヌずしお扱うこずで、 into 句を䜿甚しおク゚リを "スプラむス" できたす。

12.23.2 ク゚リ匏のあいたいさ

ク゚リ匏では、さたざたなコンテキスト キヌワヌド (§6.4.4): ascending、 by、 descending、 equals、 from、 group、 into、 join、 let、 on、 orderby、 select および whereを䜿甚したす。

これらの識別子をキヌワヌドず単玔名の䞡方ずしお䜿甚するこずによっお生じる可胜性のあるあいたいさを回避するために、これらの識別子は、"@" (§6.4.4) でプレフィックスが付いおいる堎合を陀き、ク゚リ匏内の任意の堎所でキヌワヌドず芋なされたす。その堎合、識別子ず芋なされたす。 このため、ク゚リ匏は、"from識別子" で始たり、その埌に ";"、"=" たたは "," を陀く任意のトヌクンで始たる任意の匏です。

12.23.3 ク゚リ匏の倉換

12.23.3.1 党般

C# 蚀語では、ク゚リ匏の実行セマンティクスは指定されたせん。 ク゚リ匏は、ク゚リ匏パタヌン (§12.23.4) に準拠するメ゜ッドの呌び出しに倉換されたす。 具䜓的には、ク゚リ匏は、Where、 Select、 SelectMany、 Join、 GroupJoin、 OrderBy、 OrderByDescending、 ThenBy、 ThenByDescending、 GroupBy、および Castずいう名前のメ゜ッドの呌び出しに倉換されたす。 これらのメ゜ッドには、 §12.23.4 で説明されおいるように、特定のシグネチャず戻り倀の型が必芁です。 これらのメ゜ッドは、ク゚リ察象のオブゞェクトのむンスタンス メ゜ッド、たたはオブゞェクトの倖郚にある拡匵メ゜ッドである堎合がありたす。 これらのメ゜ッドは、ク゚リの実際の実行を実装したす。

ク゚リ匏からメ゜ッド呌び出しぞの倉換は、型バむンディングたたはオヌバヌロヌドの解決が実行される前に発生する構文マッピングです。 ク゚リ匏の翻蚳埌、結果のメ゜ッド呌び出しは通垞のメ゜ッド呌び出しずしお凊理され、コンパむル時゚ラヌが明らかにされる可胜性がありたす。 これらの゚ラヌ条件には、存圚しないメ゜ッド、間違った型の匕数、型掚論が倱敗するゞェネリック メ゜ッドが含たれたすが、これらに限定されたせん。

ク゚リ匏は、さらなる削枛が䞍可胜になるたで、次の翻蚳を繰り返し適甚するこずによっお凊理されたす。 翻蚳はアプリケヌションの順序で䞀芧衚瀺されたす。各セクションでは、前のセクションの翻蚳が完党に実行されおいるこずを前提ずしおおり、䜿い果たされるず、同じク゚リ匏の凊理でセクションが埌で再怜蚎されるこずはありたせん。

範囲倉数ぞの代入を含めるク゚リ匏のコンパむル時゚ラヌです。たたは、参照たたは出力パラメヌタヌの匕数ずしお範囲倉数を䜿甚したす。

特定の翻蚳では、*で瀺された透過的な識別子を持぀範囲倉数が挿入されたす。 これらは、 §12.23.3.8 で詳しく説明されおいたす。

12.23.3.2 継続を含むク゚リ匏

ク゚リ本文に続く継続されるク゚リ匏

from «x1» in «e1» «b1» into «x2» «b2»

ず翻蚳されたす

from «x2» in ( from «x1» in «e1» «b1» ) «b2»

次のセクションの翻蚳では、ク゚リに継続がないこずを前提ずしおいたす。

䟋: 䟋

from c in customers
group c by c.Country into g
select new { Country = g.Key, CustCount = g.Count() }

次のように翻蚳されたす。

from g in
   (from c in customers
   group c by c.Country)
select new { Country = g.Key, CustCount = g.Count() }

最埌の翻蚳は次のずおりです。

customers.
GroupBy(c => c.Country).
Select(g => new { Country = g.Key, CustCount = g.Count() })

終了サンプル

12.23.3.3 明瀺的な範囲倉数型

範囲倉数型を明瀺的に指定する from 句

from «T» «x» in «e»

ず翻蚳されたす

from «x» in ( «e» ) . Cast < «T» > ( )

範囲倉数型を明瀺的に指定する join 句

join «T» «x» in «e» on «k1» equals «k2»

ず翻蚳されたす

join «x» in ( «e» ) . Cast < «T» > ( ) on «k1» equals «k2»

次のセクションの翻蚳では、ク゚リに明瀺的な範囲倉数型がないこずを前提ずしおいたす。

䟋: その䟋

from Customer c in customers
where c.City == "London"
select c

ず翻蚳されたす

from c in (customers).Cast<Customer>()
where c.City == "London"
select c

最埌の翻蚳は次のずおりです

customers.
Cast<Customer>().
Where(c => c.City == "London")

終了サンプル

泚: 明瀺的な範囲倉数型は、非ゞェネリック IEnumerable むンタヌフェむスを実装するコレクションに察しおク゚リを実行する堎合に䟿利ですが、ゞェネリック IEnumerable<T> むンタヌフェむスは䜿甚できたせん。 䞊蚘の䟋では、顧客が ArrayList型の堎合です。 泚釈

12.23.3.4 ク゚リ匏の生成を解陀する

ク゚リ匏の圢匏

from «x» in «e» select «x»

ず翻蚳されたす

( «e» ) . Select ( «x» => «x» )

䟋: その䟋

from c in customers
select c

ず翻蚳されたす

(customers).Select(c => c)

終了サンプル

劣化ク゚リ匏ずは、゜ヌスの芁玠を自明的に遞択する匏です。

泚: 翻蚳の埌のフェヌズ (§12.23.3.6 および §12.23.3.7) では、他の翻蚳手順で導入された退化したク゚リを゜ヌスに眮き換えるこずで削陀されたす。 ただし、ク゚リ匏の結果が゜ヌス オブゞェクト自䜓にならないようにするこずが重芁です。 そうしないず、このようなク゚リの結果を返すず、プラむベヌト デヌタ (芁玠配列など) が呌び出し元に誀っお公開される可胜性がありたす。 したがっお、この手順では、゜ヌスで Select を明瀺的に呌び出すこずによっお、゜ヌス コヌドで盎接蚘述された退化ク゚リを保護したす。 その埌、これらのメ゜ッドが゜ヌス オブゞェクト自䜓を返さないこずを保蚌するのは、 Select およびその他のク゚リ挔算子の実装者にかかっおいたす。 泚釈

12.23.3.5 From、let、where、join、orderby 句

2 番目の from 句の埌に select 句が続くク゚リ匏

from «x1» in «e1»  
from «x2» in «e2»  
select «v»

ず翻蚳されたす

( «e1» ) . SelectMany( «x1» => «e2» , ( «x1» , «x2» ) => «v» )

䟋: その䟋

from c in customers
from o in c.Orders
select new { c.Name, o.OrderID, o.Total }

ず翻蚳されたす

(customers).
SelectMany(c => c.Orders,
(c,o) => new { c.Name, o.OrderID, o.Total }
)

終了サンプル

2 ぀目の from 句の埌に、空でないク゚リ本文句のセットを含むク゚リ本文 Q があるク゚リ匏。

from «x1» in «e1»
from «x2» in «e2»
Q

ず翻蚳されたす

from * in («e1») . SelectMany( «x1» => «e2» ,
                              ( «x1» , «x2» ) => new { «x1» , «x2» } )
Q

䟋: その䟋

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

ず翻蚳されたす

from * in (customers).
   SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

最埌の翻蚳は次のずおりです

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.OrderID, x.o.Total })

ここで、x はコンパむラによっお生成された識別子であり、それ以倖の堎合は非衚瀺でアクセスできたせん。

終了サンプル

let 匏ずその前の from 句:

from «x» in «e»  
let «y» = «f»  
...

ず翻蚳されたす

from * in ( «e» ) . Select ( «x» => new { «x» , «y» = «f» } )  
...

䟋: その䟋

from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new { o.OrderID, Total = t }

ず翻蚳されたす

from * in (orders).Select(
    o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) })
where t >= 1000
select new { o.OrderID, Total = t }

最埌の翻蚳は次のずおりです

orders
    .Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) })
    .Where(x => x.t >= 1000)
    .Select(x => new { x.o.OrderID, Total = x.t })

ここで、x はコンパむラによっお生成された識別子であり、それ以倖の堎合は非衚瀺でアクセスできたせん。

終了サンプル

where 匏ずその前の from 句:

from «x» in «e»  
where «f»  
...

ず翻蚳されたす

from «x» in ( «e» ) . Where ( «x» => «f» )  
...

join 句の盎埌に select 句が続く

from «x1» in «e1»  
join «x2» in «e2» on «k1» equals «k2»  
select «v»

ず翻蚳されたす

( «e1» ) . Join( «e2» , «x1» => «k1» , «x2» => «k2» , ( «x1» , «x2» ) => «v» )

䟋: その䟋

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new { c.Name, o.OrderDate, o.Total }

ず翻蚳されたす

(customers).Join(
   orders,
   c => c.CustomerID, o => o.CustomerID,
   (c, o) => new { c.Name, o.OrderDate, o.Total })

終了サンプル

join 句の埌にク゚リ本文句が続きたす。

from «x1» in «e1»  
join «x2» in «e2» on «k1» equals «k2»  
...

ず翻蚳されたす

from * in ( «e1» ) . Join(  
«e2» , «x1» => «k1» , «x2» => «k2» ,
( «x1» , «x2» ) => new { «x1» , «x2» })  
...

join - into の句の盎埌に select の句が続く

from «x1» in «e1»  
join «x2» in «e2» on «k1» equals «k2» into «g»  
select «v»

ず翻蚳されたす

( «e1» ) . GroupJoin( «e2» , «x1» => «k1» , «x2» => «k2» ,
                     ( «x1» , «g» ) => «v» )

join into 句の埌にク゚リ本文句が続きたす。

from «x1» in «e1»  
join «x2» in «e2» on «k1» equals «k2» into *g»  
...

ず翻蚳されたす

from * in ( «e1» ) . GroupJoin(  
   «e2» , «x1» => «k1» , «x2» => «k2» , ( «x1» , «g» ) => new { «x1» , «g» })
...

䟋: その䟋

from c in customers
join o in orders on c.CustomerID equals o.CustomerID into co
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }

ず翻蚳されたす

from * in (customers).GroupJoin(
    orders,
    c => c.CustomerID,
    o => o.CustomerID,
    (c, co) => new { c, co })
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }

最埌の翻蚳は次のずおりです

customers
    .GroupJoin(
        orders,
        c => c.CustomerID,
        o => o.CustomerID,
        (c, co) => new { c, co })
    .Select(x => new { x, n = x.co.Count() })
    .Where(y => y.n >= 10)
    .Select(y => new { y.x.c.Name, OrderCount = y.n })

ここで、 x ず y は、コンパむラ生成識別子であり、それ以倖の堎合は非衚瀺でアクセスできたせん。

終了サンプル

orderby 節ずその前の from 節:

from «x» in «e»  
orderby «k1» , «k2» , ... , «kn»  
...

ず翻蚳されたす

from «x» in ( «e» ) .
OrderBy ( «x» => «k1» ) .
ThenBy ( «x» => «k2» ) .
... .
ThenBy ( «x» => «kn» )
...

ordering 句で降順むンゞケヌタヌが指定されおいる堎合は、代わりに OrderByDescending たたは ThenByDescending の呌び出しが生成されたす。

䟋: その䟋

from o in orders
orderby o.Customer.Name, o.Total descending
select o

最終的な翻蚳がありたす

(orders)
    .OrderBy(o => o.Customer.Name)
    .ThenByDescending(o => o.Total)

終了サンプル

次の翻蚳では、 let、 where、 join 句、たたは orderby 句がなく、各ク゚リ匏に含たれる最初の from 句が 1 ぀以䞋であるこずを前提ずしおいたす。

12.23.3.6 Select 句

ク゚リ匏の圢匏

from «x» in «e» select «v»

ず翻蚳されたす

( «e» ) . Select ( «x» => «v» )

«v» が識別子 «x» である堎合を陀き、翻蚳は単玔に

( «e» )

䟋: その䟋

from c in customers.Where(c => c.City == "London")
select c

は単に次のように翻蚳されたす

(customers).Where(c => c.City == "London")

終了サンプル

12.23.3.7 Group 句

group 句

from «x» in «e» group «v» by «k»

ず翻蚳されたす

( «e» ) . GroupBy ( «x» => «k» , «x» => «v» )

«v» が識別子 «x» である堎合を陀き、翻蚳は、

( «e» ) . GroupBy ( «x» => «k» )

䟋: その䟋

from c in customers
group c.Name by c.Country

ず翻蚳されたす

(customers).GroupBy(c => c.Country, c => c.Name)

終了サンプル

12.23.3.8 透過的な識別子

特定の倉換では、で瀺されるs を持぀範囲倉数が挿入されたす。 透過的な識別子は、ク゚リ匏倉換プロセスの䞭間ステップずしおのみ存圚したす。

ク゚リ倉換によっお透過的な識別子が挿入されるず、さらに倉換手順を実行するず、透過的な識別子が匿名関数ず匿名オブゞェクト初期化子に䌝達されたす。 これらのコンテキストでは、透過的な識別子には次の動䜜がありたす。

  • 透過的な識別子が匿名関数のパラメヌタヌずしお発生するず、関連付けられた匿名型のメンバヌは、匿名関数の本䜓のスコヌプ内で自動的に有効になりたす。
  • 透過的な識別子を持぀メンバヌがスコヌプ内にある堎合、そのメンバヌのメンバヌもスコヌプ内にありたす。
  • 透過的な識別子が匿名オブゞェクト初期化子のメンバヌ宣蚀子ずしお発生するず、透過的な識別子を持぀メンバヌが導入されたす。

䞊蚘の倉換手順では、透過的な識別子は、耇数の範囲倉数を 1 ぀のオブゞェクトのメンバヌずしおキャプチャするこずを目的ずしお、匿名型ず共に垞に導入されたす。 C# の実装では、匿名型ずは異なるメカニズムを䜿甚しお耇数の範囲倉数をグルヌプ化できたす。 次の翻蚳の䟋では、匿名型が䜿甚されるこずを前提ずし、透過的な識別子の 1 ぀の翻蚳の可胜性を瀺しおいたす。

䟋: その䟋

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }

ず翻蚳されたす

from * in (customers).SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }

さらに に倉換されたす

customers
    .SelectMany(c => c.Orders, (c,o) => new { c, o })
    .OrderByDescending(* => o.Total)
    .Select(\* => new { c.Name, o.Total })

この堎合、透過的識別子が消去されるず、次ず同等になりたす。

customers
    .SelectMany(c => c.Orders, (c,o) => new { c, o })
    .OrderByDescending(x => x.o.Total)
    .Select(x => new { x.c.Name, x.o.Total })

ここで、x はコンパむラによっお生成された識別子であり、それ以倖の堎合は非衚瀺でアクセスできたせん。

䟋

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

ず翻蚳されたす

from * in (customers).Join(
    orders,
    c => c.CustomerID,
    o => o.CustomerID,
    (c, o) => new { c, o })
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

さらに次たで枛少したす

customers
    .Join(orders, c => c.CustomerID,
        o => o.CustomerID, (c, o) => new { c, o })
    .Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d })
    .Join(products, * => d.ProductID, p => p.ProductID,
        (*, p) => new { c.Name, o.OrderDate, p.ProductName })

最埌の翻蚳は次のずおりです

customers
    .Join(orders, c => c.CustomerID,
        o => o.CustomerID, (c, o) => new { c, o })
    .Join(details, x => x.o.OrderID, d => d.OrderID, (x, d) => new { x, d })
    .Join(products, y => y.d.ProductID, p => p.ProductID,
        (y, p) => new { y.x.c.Name, y.x.o.OrderDate, p.ProductName })

ここで、 x ず y は、コンパむラ生成識別子であり、それ以倖の堎合は非衚瀺でアクセスできたせん。 終了サンプル

12.23.4 ク゚リ匏パタヌン

ク゚リ匏パタヌン は、型がク゚リ匏をサポヌトするために実装できるメ゜ッドのパタヌンを確立したす。

パブリック メンバヌ メ゜ッドずパブリックにアクセス可胜な拡匵メ゜ッドを次のクラス定矩に眮き換えるこずができる堎合、ゞェネリック型 C<T> はク゚リ匏パタヌンをサポヌトしたす。 メンバヌずアクセス可胜な拡匵メ゜ッドは、ゞェネリック型 C<T>の "shape" ず呌ばれたす。 ゞェネリック型は、パラメヌタヌず戻り倀の型の間の適切な関係を瀺すために䜿甚されたすが、非ゞェネリック型のパタヌンも実装できたす。

delegate R Func<T1,R>(T1 arg1);
delegate R Func<T1,T2,R>(T1 arg1, T2 arg2);

class C
{
    public C<T> Cast<T>() { ... }
}

class C<T> : C
{
    public C<T> Where(Func<T,bool> predicate) { ... }
    public C<U> Select<U>(Func<T,U> selector) { ... }
    public C<V> SelectMany<U,V>(Func<T,C<U>> selector,
        Func<T,U,V> resultSelector) { ... }
    public C<V> Join<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
        Func<U,K> innerKeySelector, Func<T,U,V> resultSelector) { ... }
    public C<V> GroupJoin<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
        Func<U,K> innerKeySelector, Func<T,C<U>,V> resultSelector) { ... }
    public O<T> OrderBy<K>(Func<T,K> keySelector) { ... }
    public O<T> OrderByDescending<K>(Func<T,K> keySelector) { ... }
    public C<G<K,T>> GroupBy<K>(Func<T,K> keySelector) { ... }
    public C<G<K,E>> GroupBy<K,E>(Func<T,K> keySelector,
        Func<T,E> elementSelector) { ... }
}

class O<T> : C<T>
{
    public O<T> ThenBy<K>(Func<T,K> keySelector) { ... }
    public O<T> ThenByDescending<K>(Func<T,K> keySelector) { ... }
}

class G<K,T> : C<T>
{
    public K Key { get; }
}

䞊蚘のメ゜ッドでは、ゞェネリック デリゲヌト型 Func<T1, R> ず Func<T1, T2, R>を䜿甚しおいたすが、パラメヌタヌず戻り倀の型で同じリレヌションシップを持぀他のデリゲヌト型たたは匏ツリヌ型も同様によく䜿甚されおいる可胜性がありたす。

泚意: C<T> ず O<T> の間で掚奚される関係により、 ThenBy メ゜ッドず ThenByDescending メ゜ッドは、OrderBy たたは OrderByDescendingの結果でのみ䜿甚できたす。 泚釈

泚意: GroupByの結果の掚奚される圢状 。シヌケンスのシヌケンスであり、各内郚シヌケンスには远加の Key プロパティがありたす。 泚釈

泚: ク゚リ匏は構文マッピングによっおメ゜ッド呌び出しに倉換されるため、型はク゚リ匏パタヌンの䞀郚たたはすべおを実装する方法に倧きな柔軟性を持ちたす。 たずえば、2 ぀の呌び出し構文が同じであり、匿名関数は䞡方に倉換できるため、メ゜ッドはデリゲヌトたたは匏ツリヌを芁求できるため、パタヌンのメ゜ッドをむンスタンス メ゜ッドたたは拡匵メ゜ッドずしお実装できたす。 䞀郚のク゚リ匏パタヌンのみを実装する型では、型がサポヌトするメ゜ッドにマップされるク゚リ匏倉換のみがサポヌトされたす。 泚釈

泚: System.Linq 名前空間は、 System.Collections.Generic.IEnumerable<T> むンタヌフェむスを実装するすべおの型に察しおク゚リ匏パタヌンの実装を提䟛したす。 泚釈

12.24 代入挔算子

12.24.1 党般

assignment
    : deconstructing_assignment
    | simple_assignment
    | compound_assignment
    | ref_assignment
    ;

入力を deconstructing_assignment ず他の代替手段の䞡方ずしお構文的に認識できる堎合は、 deconstructing_assignment を遞択する必芁がありたす。

泚: ANTLR 文法セマンティクスでは、代替手段の順序付けにより、この芁件が適甚されたす。 意味的には 、4 ぀の遞択肢の間に重耇はありたせん。これは構文的なあいたいさです。

simple_assignment匏ずcompound_assignment匏は、倉数、プロパティ、たたはむンデクサヌ芁玠に新しい倀を割り圓おたす。 compound_assignmentのサブセットであるむベントの割り圓お (§12.24.6) は、むベントに新しい倀を割り圓おたす。 ref_assignment匏は、倉数参照 (§9.5) を参照倉数 (§9.7) に割り圓おたす。 deconstructing_assignmentは、デコンストラクタヌの非砎棄タヌゲットに倀を割り圓おたす。

simple_assignment、ref_assignment、たたはdeconstructing_assignmentのタヌゲットのタヌゲットは、砎棄 (§9.2.9.2) にするこずができたす。 compound_assignmentの巊オペランドは砎棄できたせん。 代入の巊オペランドが砎棄の堎合、察応する右蟺匏が評䟡されたすが、倀は栌玍されたせん。

各代替手段は、同じ䞀般的な圢匏の l <op> rを受け取りたす。ここで、 <op> は 代入挔算子です。 代入挔算子は右結合性を持っおいたす。぀たり、操䜜は右から巊にグルヌプ化されたす。

䟋: a = b = c 圢匏の匏を a = (b = c)ずしお評䟡したす。 終了サンプル

泚: むベント割り圓お §12.24.6 で指定されおいるように、+=挔算子ず-=挔算子の巊オペランドがむベント アクセスずしお分類された堎合、compound_assignmentは倀を生成しないため、e1 += e2 += fずe1がむベント アクセスであるe2フォヌムの匏は無効であり、右関連付けではありたせん。

12.24.2 単玔な割り圓お

simple_assignment
    : unary_expression '=' expression
    ;

単玔代入では、 = 挔算子は 単玔代入挔算子ず呌ばれたす。 巊オペランドが砎棄でない堎合、匏は右オペランドの倀を巊オペランドによっお指定された倉数、プロパティ、たたはむンデクサヌ芁玠に割り圓おたす。 巊オペランドが砎棄の堎合、右オペランドは評䟡されたすが、倀は栌玍されたせん。 単玔代入挔算子の巊オペランドは、 §15.8.2 で説明されおいるむベント アクセスにするこずもできたす。

単玔代入の巊オペランドが E.P 圢匏たたは E[Eáµ¢] で、 E がコンパむル時の型 dynamicを持぀堎合、代入は動的にバむンドされたす (§12.3.3)。 この堎合、代入匏のコンパむル時の型が dynamicされ、次に瀺す解決は実行時に Eの型に基づいお実行されたす。 巊オペランドが圢匏 E[Eáµ¢] で、 Eáµ¢ の少なくずも 1 ぀の芁玠がコンパむル時型 dynamicを持ち、 E のコンパむル時の型が配列でない堎合、結果のむンデクサヌ アクセスは動的にバむンドされたすが、コンパむル時のチェックは制限されたす (§12.6.5)。

単玔な代入 x = y の型は、 xの y ぞの割り圓おの型であり、次のように再垰的に決定されたす。

  • xが倉数ずしお分類されおいる堎合、倉数はreadonlyされず、xは型Tを持ち、yはTぞの暗黙的な倉換を持ち、代入には型Tがありたす。
  • それ以倖の堎合、 x が暗黙的に型指定された倉数 (぀たり、暗黙的に型指定された宣蚀匏) ずしお分類され、 y が型 Tを持぀堎合、倉数の掚論された型は Tであり、代入の型は Tです。
  • それ以倖の堎合、 x がプロパティアクセスたたはむンデクサヌアクセスずしお分類されおいる堎合、プロパティたたはむンデクサヌはアクセス可胜なセットたたは初期化アクセサヌを持ち、 x は型 Tを持ち、 y は Tぞの暗黙的な倉換を持ち、代入は型 Tを持぀。
  • それ以倖の堎合、割り圓おが有効ではなく、バむンド時゚ラヌが発生したす。

型が x = y のフォヌム T の単玔な割り圓おの実行時凊理は、次の再垰的な手順で構成される、 x型を持぀ y の T ぞの割り圓おずしお実行されたす。

  • x は、ただ評䟡されおいない堎合に評䟡されたす。
  • x が倉数ずしお分類されおいる堎合、 y が評䟡され、必芁に応じお暗黙的な倉換 (T) を䜿甚しお に倉換されたす。
    • x によっお指定された倉数が reference_typeの配列芁玠である堎合は、実行時チェックが実行され、 y に察しお蚈算された倀が、 x が芁玠である配列むンスタンスず互換性があるこずを確認したす。 y が nullである 堎合、たたは暗黙的な参照倉換 (§10.2.8) が、 y によっお参照されるむンスタンスの型から、 xを含む配列むンスタンスの実際の芁玠型に存圚する堎合、チェックは成功したす。 それ以倖の堎合は、System.ArrayTypeMismatchException がスロヌされたす。
    • y の評䟡ず倉換によっお埗られた倀は、 xの評䟡によっお䞎えられた堎所に栌玍され、割り圓おの結果ずしお生成されたす。
  • x がプロパティたたはむンデクサヌ アクセスずしお分類される堎合:
    • y が評䟡され、必芁に応じお暗黙的な倉換 (T) を䜿甚しお に倉換されたす。
    • xの set アクセサヌたたは init アクセサヌは、yの評䟡ず倉換に起因する倀をその倀匕数ずしお呌び出したす。
    • yの評䟡ず倉換に起因する倀は、単玔代入匏の結果ずしお生成されたす。

泚意: x のコンパむル時の型が dynamic で、 y のコンパむル時の型から dynamicぞの暗黙的な倉換がある堎合、実行時の解決は必芁ありたせん。 泚釈

泚: 配列の共分散芏則 (§17.6) により、配列型 A[] の倀は、配列型 B[]のむンスタンスぞの参照にするこずができたす。ただし、B から Aぞの暗黙的な参照倉換が存圚する堎合に限りたす。 これらの芏則により、 reference_type の配列芁玠ぞの割り圓おには、割り圓おられおいる倀が配列むンスタンスず互換性があるこずを確認するための実行時チェックが必芁です。 この䟋では

string[] sa = new string[10];
object[] oa = sa;
oa[0] = null;              // OK
oa[1] = "Hello";           // OK
oa[2] = new ArrayList();   // ArrayTypeMismatchException

最埌の代入は、System.ArrayTypeMismatchException ぞの参照が、ArrayList 芁玠に栌玍できないこずが原因で string[] をスロヌする原因ずなりたす。

泚釈

struct_type で宣蚀されたプロパティたたはむンデクサヌが代入のタヌゲットである堎合、プロパティたたはむンデクサヌ アクセスに関連付けられおいるむンスタンス匏は倉数ずしお分類されたす。 むンスタンス匏が倀ずしお分類されるず、バむンド時゚ラヌが発生したす。

泚: §12.8.7のため、フィヌルドにも同じルヌルが適甚されたす。 泚釈

䟋: 宣蚀を指定したす:

struct Point
{
    int x, y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return y; }
        set { y = value; }
    }
}

struct Rectangle
{
    Point a, b;

    public Rectangle(Point a, Point b)
    {
        this.a = a;
        this.b = b;
    }

    public Point A
    {
        get { return a; }
        set { a = value; }
    }

    public Point B
    {
        get { return b; }
        set { b = value; }
    }
}

この䟋では

Point p = new Point();
p.X = 100;
p.Y = 100;
Rectangle r = new Rectangle();
r.A = new Point(10, 10);
r.B = p;

p.X ず p.Y は倉数であるため、 r.A、 r.B、 p、および r ぞの割り圓おは蚱可されたす。 ただし、この䟋では

Rectangle r = new Rectangle();
r.A.X = 10;
r.A.Y = 10;
r.B.X = 100;
r.B.Y = 100;

r.A ず r.B は倉数ではないため、代入はすべお無効です。

終了サンプル

12.24.3 割り圓おの分解

12.24.3.1 党般

deconstructing_assignment
    : deconstructor '=' expression
    ;

deconstructor
    : '(' deconstructor_element (',' deconstructor_element)+ ')'
    | abridged_deconstructor
    ;

deconstructor_element
    : deconstructor
    | declaration_expression
    | discard_token
    | variable_reference
    ;

泚: abridged_deconstructor は 分解子 の短瞮衚蚘であり、以䞋で説明したす (§12.24.3.2)。

分解代入では、 = 挔算子は 分解代入挔算子ず呌ばれたす。

入力を構文的に認識できる堎合に deconstructor_element を認識する堎合:

  • 分解 子 ずしお、 およびvariable_referenceずしお;たたは
  • discard_tokenずしお、そしおvariable_referenceずしお;

その埌、それぞれの堎合、前者が遞択されたす。

メモ 代替候補が䞀芧衚瀺される順序に基づいお、ANTLR 文法セマンティクスによっおこれらの優先順䜍が適甚されたす。 泚釈

䞋䜍互換性のために 、いずれかのdeconstructor_element が discard_token である堎合は、次のようにしたす。

  • "" の名前参照 (_) で関連付けられおいる宣蚀が芋぀かるず、discard_tokenはsimple_nameずしお再分類され、構文的にはvariable_referenceになりたす。
  • それ以倖の堎合、 砎棄トヌクン は単玔な砎棄 (§12.20) です。

deconstructor_elementずしお発生する再分類されたdiscard_tokenを含むvariable_referenceが曞き蟌み䞍可の堎合、コンパむル時゚ラヌになりたす。

文法で衚珟されおいない特定のコンテキストで有効な deconstructor_elementには制限がありたす。

  • 単玔な砎棄 (䞊蚘のvariable_referenceずしお再分類されおいないdiscard_token) は、declaration_expressionでもvariable_referenceずしおも扱われたせん。任意のコンテキストでdeconstructor_elementずしお発生する可胜性があり、他の芁玠に適甚される制限には圱響したせん。
  • declaration_expressionは、包含する分解子がステヌトメントの先頭たたはfor_initializerのメンバヌにある堎合にのみ発生したす。

これらの制限の堎合:

  • 別の デコンストラクタヌの deconstructor_elementずしお入れ子になったデ コンストラクタヌ は、最も倖にあるデ コンストラクタヌによっお "包含" されたす。
  • abridged_deconstructor (§12.24.3.2) の短瞮圢は、declaration_expressionのコレクションずしお展開された圢匏ずしお扱われたす。
  • "ステヌトメントの開始時" ずは、分解子が掟生 ステヌトメント ➜ embedded_statement ➜expression_statement statement_expression ➜ statement_expression ➜ deconstructing_assignment ➜ 分解子の䞀郚ずしお認識され、 deconstructing_assignmentが発生する可胜性がある他の堎所では認識されないこずを意味したす。そしお
  • "for_initializerのメンバヌ" は、デコンストラクタヌが掟生for_initializer ➜statement_expression_list ➜statement_expression➜deconstructing_assignment➜分解子の䞀郚ずしお認識され、deconstructing_assignmentが発生する可胜性がある他の堎所では認識されないこずを意味したす。

フォヌム d = yの分解割り圓おのコンパむル時の凊理 (dは arity を持぀フォヌム (d₁, ..., dₙ)のn) は、次のように凊理されたす。

  • 代入の右オペランド (y) は分解され (§12.7)、eが生成されたす。(e₁, ..., eₘ)堎合はコンパむル時゚ラヌです。
  • 割り圓おの型 T が決定されたす。ここで、 T はタプル型 (T₁, ..., Tₙ) であり、各 Táµ¢ は、察応する dáµ¢ ず eᵢに基づいお次のように蚈算されたす。
    • dᵢが砎棄であり、eᵢが型Eᵢを持぀堎合、TᵢはEᵢ。
    • それ以倖の堎合、 dáµ¢ が 分解子 の堎合、 Táµ¢ は、このコンパむル時アルゎリズムを再垰的に適甚するこずによっお決定される dáµ¢ = eáµ¢ の型になりたす。
    • それ以倖の堎合 dáµ¢ 型 Dáµ¢ があり、 eáµ¢ から Dᵢぞの暗黙的な倉換がある堎合、 Táµ¢ は Dᵢ。
    • それ以倖の堎合、 dáµ¢ ず eáµ¢ は互換性がありたせん。コンパむル時゚ラヌが発生したす。

分解割り圓おの実行時凊理 (珟圚は d = e) は、次のように凊理されたす。

  1. 次の手順では、各 dáµ¢ ず eáµ¢ を巊から右に 1 回だけ評䟡する必芁がありたす。 混乱を避けるために、これはすべおの dáµ¢ が eᵢの前に評䟡され、入れ子になった 分解子たたは tuple_literalが存圚する堎合、順序は深さ優先です。
  2. t圢匏のタプル倀(t₁, ..., tₙ)は、暗黙的なタプル倉換 (e) を䜿甚しおTをに倉換するこずによっお䜜成されたす。
  3. 砎棄されおいない各 dáµ¢ を巊から右に順に䞊べ替えたす。
    • dᵢが倉数参照である堎合は、単玔な代入dáµ¢ = tᵢが実行されたす。
    • それ以倖の堎合、 dáµ¢ は入れ子になった 分解子 であり、この手順 (3) は dáµ¢ ず tᵢの芁玠に再垰的に適甚されたす。
  4. deconstructing_assignment匏党䜓の型ず倀は、それぞれTずt。

泚: 各 dáµ¢ ず eáµ¢ が巊から右に 1 回だけ評䟡されるずいう芁件により、評䟡の副䜜甚はすべお 1 回だけ実行され、 dáµ¢/eáµ¢ 間の䟝存関係はすべお正しく評䟡されたす。 泚釈

泚: このアルゎリズムによっお生成される䞭間タプルの構築は、 §8.3.11.2 で指定されおいる実装によっお省略される堎合がありたす。 泚釈

䟋: 砎棄は variable_referenceではなくプレヌスホルダヌであるため、分解代入の巊偎にある既存の倉数ず組み合わせるこずができたす。

int x = 0;
(x, _) = (1, 2); // assigns 1 to the existing variable x; the discard ignores 2
Console.WriteLine(x);

終了サンプル

12.24.3.2 ブリッゞドデコンストラクタヌ

abridged_deconstructorは、暗黙的に型指定された宣蚀匏を含む分解子の短瞮構文です。

abridged_deconstructor
    : 'var' abridged_deconstructor_elements
    ;

abridged_deconstructor_elements
    : '(' abridged_deconstructor_element (',' abridged_deconstructor_element)+ ')'
    ;

abridged_deconstructor_element
    : identifier
    | abridged_deconstructor_elements
    ;

abridged_deconstructorvar (e1, ..., en)は分解子の短瞮圢であり(var e1, ..., var en)暙準の (ブリッゞされおいない) 拡匵 (§12.24.3.1) ず同じ動䜜をしたす。 これは、abridged_deconstructor内の入れ子になった abridged_deconstructor_elementに 再垰的に適甚されたす。 したがっお、 abridged_deconstructor 内に入れ子になった各識別子は、宣蚀匏 (§12.20) を導入したす。

䟋: 次の 2 ぀の䟋では、どちらも 2 ぀の倉数 a ず b を宣蚀しおいたす。 1 ぀目は、明瀺的に型指定された倉数を導入する暙準分解子を䜿甚したす。2 ぀目は、同じ倉数を宣蚀し、暗黙的に型指定するabridged_deconstructorです。この堎合、2 番目の定数は、Lがbされるようにlongサフィックスに必芁です。

// standard deconstructor
(int a, long b) = (1, 2); // a is 1, b is 2

// equivalent abridged_deconstructor
var (c, d) = (1, 2L);     // note the L suffix so d is inferred as long

割り圓おの個々の芁玠は、それ自䜓を分解匏にするこずができたす。 たずえば、次の分解匏は、aを介しおf、6 ぀の倉数を割り圓おたす。

var (a, b, (c, d, (e, f))) = (1, 2, (3, 4, (5, 6)));

この䟋では、入れ子になったタプルの構造が割り圓おの䞡偎で䞀臎する必芁があるこずに泚意しおください。

巊偎の倉数が暗黙的に型指定されおいる堎合、察応する匏には次の型が必芁です。

(int a, string? b) = (42, null); // OK, LHS typed
var (c, d) = (42, null);         // Invalid as type of d cannot be inferred
(int e, var f) = (42, null);     // Invalid as type of f cannot be inferred
var (g, h) = (10, "text");       // OK, RHS typed
(var i, var j) = (10, "text");   // OK, RHS typed
(var k, string l) = (42, null);  // OK, for each LHS/RHS element pair one is typed

終了サンプル

12.24.4 Ref 代入

ref_assignment
    : unary_expression '=' 'ref' expression
    ;

= ref 挔算子は、 ref 代入挔算子ず呌ばれたす。 この匏は、右オペランドを巊オペランドで指定された参照倉数の参照先にしたす。

巊オペランドは、参照倉数 (§9.7)、参照パラメヌタヌ ( this以倖)、出力パラメヌタヌ、入力パラメヌタヌ、たたは砎棄にバむンドする匏でなければなりたせん。 巊オペランドが砎棄の堎合、右オペランドは評䟡されたすが、倉数参照は栌玍されたせん。 それ以倖の堎合、右オペランドは、巊オペランドず同じ型の倀を指定する variable_reference (§9.5) を生成する匏になりたす。

右オペランドの ref-safe コンテキストは、少なくずも巊オペランドの ref-safe コンテキストず同じ幅で、巊偎のオペランドは右オペランド (§9.7.2) ず同じセヌフ コンテキストを持぀必芁がありたす。

泚: この芁件は、ref 䜍眮によっお指される倀の有効期間が䞍倉であるために存圚したす。 間接参照により、有効期間を狭くする堎合でも、ここでどのような皮類の分散も蚱可されなくなりたす。 泚釈

右オペランドは、ref 代入の時点で確実に割り圓おられたす。

巊オペランドが出力パラメヌタヌにバむンドする堎合、その出力パラメヌタヌが ref 代入挔算子の先頭に確実に割り圓おられおいない堎合ぱラヌになりたす。

巊オペランドが曞き蟌み可胜な ref (぀たり、 ref readonly ロヌカルパラメヌタヌたたは入力パラメヌタヌ以倖のものを指定する) の堎合、右オペランドは曞き蟌み可胜な variable_referenceになりたす。 右オペランド倉数が曞き蟌み可胜な堎合、巊オペランドは曞き蟌み可胜たたは読み取り専甚の ref である可胜性がありたす。

この挔算により、巊オペランドが右オペランド倉数の別名になりたす。 右オペランド倉数が曞き蟌み可胜な堎合でも、゚むリアスを読み取り専甚にするこずができたす。

ref 代入挔算子は、割り圓おられた型の variable_reference を生成したす。 巊オペランドが曞き蟌み可胜な堎合は曞き蟌み可胜です。

ref 代入挔算子は、右オペランドによっお参照されるストレヌゞの堎所を読み取らないものずしたす。

䟋: = refの䜿甚䟋を次に瀺したす。

public static int M1() { ... }
public static ref int M2() { ... }
public static ref uint M2u() { ... }
public static ref readonly int M3() { ... }
public static void Test()
{
    int v = 42;
    ref int r1 = ref v; // OK, r1 refers to v, which has value 42
    r1 = ref M1();      // Error; M1 returns a value, not a reference
    r1 = ref M2();      // OK; makes an alias
    r1 = ref M2u();     // Error; lhs and rhs have different types
    r1 = ref M3();      // Error; M3 returns a ref readonly, which r1 cannot honor
    ref readonly int r2 = ref v; // OK; make readonly alias to ref
    r2 = ref M2();      // OK; makes an alias, adding read-only protection
    r2 = ref M3();      // OK; makes an alias and honors the read-only
    r2 = ref (r1 = ref M2());  // OK; r1 is an alias to a writable variable,
                               //     r2 is an alias (with read-only access)
                               //     to the same variable
}

終了サンプル

泚意: = ref 挔算子を䜿甚しおコヌドを読み取るずき、オペランドの䞀郚ずしお ref 郚分を読み取りたくなる可胜性がありたす。 これは、オペランドが条件付き ?: 匏である堎合に特に混乱したす。 たずえば、 ref int a = ref b ? ref x : ref y; を読み取る堎合は、挔算子である = ref 、 b ? ref x : ref y 右オペランドずしお読み取る必芁 ref int a = ref (b ? ref x : ref y);。 重芁なのは、匏 ref b が䞀芋ステヌトメントの䞀郚ずしお芋えおも、実際にはそのステヌトメントの䞀郚ではないずいうこずです。 泚釈

12.24.5 耇合代入

compound_assignment
    : unary_expression compound_assignment_operator expression
    ;

compound_assignment_operator
    : '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '??='
    | right_shift_assignment
    | unsigned_right_shift_assignment
    ;

compound_assignment_operatorの挔算子は、耇合代入挔算子ず呌ばれたす。

耇合代入挔算子の巊オペランドは砎棄できたせん (§9.2.9.2)。

巊偎のオペランドずしおむベント アクセス匏を持぀ += 挔算子ず -= 挔算子は、 むベント代入挔算子ず呌ばれたす。 巊偎のオペランドずしおむベント アクセスを持぀他の耇合代入挔算子は有効ではありたせん。 むベント代入挔算子に぀いおは、 §12.24.6 を参照しおください。

耇合代入の巊オペランドが E.P 圢匏たたは E[Eáµ¢] で、 E がコンパむル時の型 dynamicを持぀堎合、代入は動的にバむンドされたす (§12.3.3)。 この堎合、代入匏のコンパむル時の型が dynamicされ、次に瀺す解決は実行時に Eの型に基づいお実行されたす。 巊オペランドが圢匏 E[Eáµ¢] で、 Eáµ¢ の少なくずも 1 ぀の芁玠がコンパむル時型 dynamicを持ち、 E のコンパむル時の型が配列でない堎合、結果のむンデクサヌ アクセスは動的にバむンドされたすが、コンパむル時のチェックは制限されたす (§12.6.5)。

匏a ??= bは(T) (a ?? (a = b))ず同じですが、aは 1 回だけ評䟡されたす。ただし、Tは、aの型が動的な堎合はbの型であり、それ以倖の堎合はTa ?? bの型です。

泚: ?? (§12.18) の定矩から b は、 a の倀が null堎合にのみ評䟡されたす。

それ以倖の堎合、 x Â«op»= y 圢匏の操䜜は、2 項挔算子のオヌバヌロヌド解決 (§12.4.5) を適甚しお、操䜜が x Â«op» y曞き蟌たれたかのように凊理されたす。 THEN

  • 遞択した挔算子の戻り倀の型が xの型に暗黙的に倉換できる堎合、操䜜は x = x Â«op» yずしお評䟡されたす。ただし、 x は 1 回だけ評䟡されたす。
  • それ以倖の堎合、遞択した挔算子が定矩枈みの挔算子である堎合、遞択した挔算子の戻り倀の型が x の型に明瀺的に倉換可胜であり、 y が x の型に暗黙的に倉換できる堎合、たたは挔算子がシフト挔算子である堎合、操䜜は x = (T)(x Â«op» y)ずしお評䟡されたす。ここで、 T は xの型です。 ただし、 x は 1 回だけ評䟡されたす。
  • それ以倖の堎合、耇合代入は無効であり、バむンド時゚ラヌが発生したす。

「䞀床だけ評䟡される」ずいう甚語は、 x Â«op» yの評䟡においお、 x の構成匏の結果が䞀時的に保存され、 xぞの割り圓おを実行するずきに再利甚されるこずを意味したす。

䟋: 代入 A()[B()] += C()では、 A は int[]を返すメ゜ッドであり、 B および C は intを返すメ゜ッドであり、メ゜ッドは A、 B、 Cの順序で 1 回だけ呌び出されたす。 終了サンプル

耇合代入の巊オペランドがプロパティ アクセスたたはむンデクサヌ アクセスである堎合、プロパティたたはむンデクサヌには get アクセサヌず set アクセサヌたたは init アクセサヌの䞡方が含たれたす。 そうでない堎合は、バむンド時゚ラヌが発生したす。

䞊蚘の 2 番目の芏則では、特定のコンテキストで x Â«op»= y を x = (T)(x Â«op» y) ずしお評䟡できたす。 この芏則は、巊オペランドが sbyte、 byte、 short、 ushort、たたは charの型である堎合に、定矩枈みの挔算子を耇合挔算子ずしお䜿甚できるように存圚したす。 䞡方の匕数がこれらの型のいずれかである堎合でも、定矩枈みの挔算子は、 intで説明されおいるように、 型の結果を生成したす。 したがっお、キャストがないず、結果を巊オペランドに割り圓おられなくなりたす。

定矩枈みの挔算子に察するルヌルの盎感的な効果は、 x «op»= y ず x Â«op» y の䞡方が蚱可されおいる堎合に x = y が蚱可されるずいうこずです。

䟋: 次のコヌド䟋の内容:

byte b = 0;
char ch = '\0';
int i = 0;
b += 1;           // OK
b += 1000;        // Error, b = 1000 not permitted
b += i;           // Error, b = i not permitted
b += (byte)i;     // OK
ch += 1;          // Error, ch = 1 not permitted
ch += (char)1;    // OK

各゚ラヌの盎感的な理由は、察応する単玔な割り圓おも゚ラヌだったずいうこずです。

終了サンプル

泚: これは、耇合代入操䜜がリフトされた挔算子をサポヌトするこずも意味したす。 耇合代入 x Â«op»= y は x = x Â«op» y たたは x = (T)(x Â«op» y)ずしお評䟡されるため、評䟡の芏則では、リフトされた挔算子が暗黙的にカバヌされたす。 泚釈

12.24.6 むベントの割り圓お

むベントの割り圓おは挔算子の巊オペランドがむベント アクセスずしお分類されるcompound_assignmentのサブセットです。 むベントの割り圓おは次のように評䟡されたす。

  • むベント アクセスのむンスタンス匏 (存圚する堎合) が評䟡されたす。
  • += 挔算子たたは -= 挔算子の右オペランドが評䟡され、必芁に応じお、暗黙的な倉換 (§10.2) を䜿甚しお巊オペランドの型に倉換されたす。
  • 前の手順で蚈算した倀で構成される匕数リストを䜿甚しお、むベントのむベント アクセサヌが呌び出されたす。 挔算子が +=された堎合は、add アクセサヌが呌び出されたす。挔算子が -=された堎合は、remove アクセサヌが呌び出されたす。

むベント割り圓お匏は倀を生成したせん。 したがっお、むベント割り圓お匏は、 statement_expression (§13.7) のコンテキストでのみ有効です。

12.25 匏

匏は、non_assignment_expression たたは assignment のいずれかです。

expression
    : non_assignment_expression
    | assignment
    ;

non_assignment_expression
    : conditional_expression
    | lambda_expression
    | query_expression
    ;

12.26 定数匏

定数匏は、コンパむル時に完党に評䟡される匏です。

constant_expression
    : conditional_expression
    ;

定数匏は、 null倀を持っおいるか、倀型たたは参照型である必芁がありたす。 定数匏に倀型がある堎合、その型は、 sbyte、 byte、 short、 ushort、 int、 uint、 nint、 nuint、 long、 ulong、 char、 float、 double、 decimal、 bool, 、たたは任意の列挙型のいずれかになりたす。 定数匏に参照型がある堎合、匏は次の条件を持぀必芁がありたす。

  • string型の倀を持぀。
  • は、参照型の既定倀の匏 (§12.8.21) です。

型のnintは、[-2147483648, 2147483647] の範囲内の倀を持぀必芁がありたす。 型のnuintは、[0, 4294967295] の範囲の倀を持぀必芁がありたす。

定数匏では、次のコンストラクトのみが蚱可されたす。

  • リテラル ( null リテラルを含みたすが、UTF-8 文字列リテラルは陀きたす)。
  • 定数補間文字列。
  • クラス、構造䜓、およびむンタヌフェむス型の const メンバヌぞの参照。
  • 列挙型のメンバヌぞの参照。
  • ロヌカル定数ぞの参照。
  • 括匧で括られた郚分匏、それ自䜓が定数匏です。
  • キャスト匏。
  • checked および unchecked 匏。
  • nameof 匏。
  • 定矩枈みの +、 -、 ! (論理吊定)、および単項挔算子 ~。
  • 定矩枈みの +、 -、 *、 /、 %、 <<、 >>、 >>>、 &、 |、 ^、 &&、 ||、 ==、 !=、 <、 >、 <=、および >= 二項挔算子。
  • ?: 条件挔算子。
  • ! null-forgiving 挔算子 (§12.8.9)。
  • sizeof アンマネヌゞ型が §24.6.9 で指定された型の 1 ぀であり、 sizeof が定数倀を返す堎合は、匏。
  • 型が䞊蚘のいずれかである堎合のデフォルト倀匏。

定数匏では、次の倉換を䜿甚できたす。

  • ID 倉換
  • 数倀倉換
  • 列挙の倉換
  • 定数匏の倉換
  • 倉換の゜ヌスが null 倀に評䟡される定数匏である堎合においお、暗黙的および明瀺的な参照倉換が行われたす。

泚:null 以倖の倀のボックス化、ボックス化解陀、暗黙的な参照倉換などのその他の倉換は、定数匏では䜿甚できたせん。 泚釈

䟋: 次のコヌド䟋の内容:

class C
{
    const object i = 5;         // error: boxing conversion not permitted
    const object str = "hello"; // error: implicit reference conversion
}

ボックス化倉換が必芁であるため、 i の初期化ぱラヌです。 str の初期化は、null 以倖の倀からの暗黙的な参照倉換が必芁であるため、゚ラヌです。

終了サンプル

匏が䞊蚘の芁件を満たすたびに、匏はコンパむル時に評䟡されたす。 これは、匏が非定数コンストラクトを含む倧きな匏の郚分匏である堎合でも圓おはたりたす。

定数匏のコンパむル時評䟡では、非定数匏の実行時評䟡ず同じ芏則が䜿甚されたす。ただし、実行時の評䟡で䟋倖がスロヌされる堎合、コンパむル時の評䟡によっおコンパむル時゚ラヌが発生する点が異なりたす。

constant_expressionのコンパむル時の評䟡では、次の倀を䜿甚したす。

  • nint型のすべおの倀をSystem.Int32ずしお扱いたす。
  • nuint型のすべおの倀をSystem.UInt32ずしお扱いたす。
  • それ以倖の堎合は、実行時の非定数匏ず同じ評䟡芏則を䜿甚したす。

nint / nuint倀がInt32/UInt32ずしお衚珟できない堎合、たたは匏党䜓の実行時評䟡で䟋倖がスロヌされる堎合は、コンパむル時゚ラヌが生成されたす。

䟋: これらの芏則は、constant_expressionずしお衚面的に有効なネむティブ敎数を含む匏は、実装で定矩された完党なネむティブ敎数粟床を䜿甚しお実行時に評䟡される匏ずしおのみ有効であるこずを意味したす。

public class C
{
    private const nint hugeNumber = int.MaxValue + 1;
}

前の䟋では、匏 int.MaxValue + 1 の結果が Int32ずしお衚珟できないため、゚ラヌが生成されたす。 nintのサむズが 32 ビットを超えるマシンでは、匏は実行時に成功したす。 終了サンプル

定数匏が unchecked コンテキストに明瀺的に配眮されおいない限り、匏のコンパむル時の評䟡䞭に敎数型の算術挔算および倉換で発生するオヌバヌフロヌは、垞にコンパむル時゚ラヌを匕き起こしたす (§12.8.20)。

定数匏は、以䞋に瀺すコンテキストで必芁です。これは、 constant_expressionを䜿甚しお文法で瀺されたす。 これらのコンテキストでは、コンパむル時に匏を完党に評䟡できない堎合、コンパむル時゚ラヌが発生したす。

  • 定数宣蚀 (§15.4)
  • 列挙メンバヌ宣蚀 (§20.4)
  • パラメヌタヌ リストの既定の匕数 (§15.6.2)
  • case ステヌトメントの switch ラベル (§13.8.3)。
  • goto case ステヌトメント (§13.10.4)
  • 初期化子を含む配列䜜成匏 (§12.8.17.4) の次元の長さ。
  • 属性 (§23)
  • constant_pattern (§11.2.3) 内

暗黙的な定数匏倉換 (§10.2.11) では、定数匏の倀が倉換先の型の範囲内にある堎合、型 int の定数匏を sbyte、 byte、 short、 ushort、 uint、 nint、 nuint、たたは ulongに倉換できたす。

12.27 ブヌル匏

boolean_expression は、bool型の結果を生成する匏です。特定のコンテキストでは次に瀺すように operator true を適甚するこずで、あるいは盎接的に結果を埗るこずができたす。

boolean_expression
    : expression
    ;

if_statement (§13.8.2)、while_statement (§13.9.2)、do_statement (§13.9.3)、たたは for_statement (§13.9.4) の制埡条件匏は boolean_expressionです。 ?:挔算子 (§12.21) の制埡条件匏は、boolean_expressionず同じ芏則に埓いたすが、挔算子の優先順䜍の理由から、null_coalescing_expressionずしお分類されたす。

boolean_expressionE は、次のように、 bool型の倀を生成できる必芁がありたす。

  • E が bool に暗黙的に倉換できる堎合は、実行時に暗黙的な倉換が適甚されたす。
  • それ以倖の堎合は、単項挔算子のオヌバヌロヌド解決 (§12.4.4) を䜿甚しお、 operator trueでの E の固有の最適な実装を芋぀け、実行時にその実装が適甚されたす。
  • このような挔算子が芋぀からない堎合は、バむンド時゚ラヌが発生したす。