Expressions

式は、演算子とオペランドのシーケンスです。An expression is a sequence of operators and operands. この章では、構文、オペランドと演算子の評価と式の意味の順序を定義します。This chapter defines the syntax, order of evaluation of operands and operators, and meaning of expressions.

式の分類Expression classifications

式は、次のいずれかに分類されます。An expression is classified as one of the following:

  • 値。A value. すべての値には、型が関連付けられています。Every value has an associated type.
  • 変数です。A variable. すべての変数は、関連付けられた型、変数の宣言型つまりを持っています。Every variable has an associated type, namely the declared type of the variable.
  • 名前空間。A namespace. この分類の式の左側にあることができますのみに、 member_access (メンバー アクセス)。An expression with this classification can only appear as the left hand side of a member_access (Member access). 他のコンテキストでは、名前空間として分類される式は、コンパイル時エラーを発生します。In any other context, an expression classified as a namespace causes a compile-time error.
  • 型。A type. この分類の式の左側にあることができますのみに、 member_access (メンバー アクセス)、またはオペランドとして、as演算子 (演算子として、)、is演算子 (、演算子は、)、またはtypeof演算子 (typeof 演算子)。An expression with this classification can only appear as the left hand side of a member_access (Member access), or as an operand for the as operator (The as operator), the is operator (The is operator), or the typeof operator (The typeof operator). 他のコンテキストでは、型として分類される式は、コンパイル時エラーを発生します。In any other context, an expression classified as a type causes a compile-time error.
  • 一連のオーバー ロードされたメソッドをメンバー検索の結果は、メソッド グループ (メンバー ルックアップ)。A method group, which is a set of overloaded methods resulting from a member lookup (Member lookup). メソッド グループには、関連付けられたインスタンス式と関連付けられている型の引数リストがあります。A method group may have an associated instance expression and an associated type argument list. インスタンス式の評価の結果になりますで表されるインスタンスがインスタンス メソッドが呼び出されたときにthis(このアクセス)。When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access). メソッド グループが許可されている、 invocation_expression (Invocation 式)、 delegate_creation_expression (デリゲートの作成式) の左側として、演算子、および互換性のあるデリゲート型に暗黙的に変換できます (メソッド グループ変換)。A method group is permitted in an invocation_expression (Invocation expressions) , a delegate_creation_expression (Delegate creation expressions) and as the left hand side of an is operator, and can be implicitly converted to a compatible delegate type (Method group conversions). 他のコンテキストでは、メソッド グループに分類される式は、コンパイル時エラーを発生します。In any other context, an expression classified as a method group causes a compile-time error.
  • Null リテラルです。A null literal. この分類の式は、参照型または null 許容型に暗黙的に変換できます。An expression with this classification can be implicitly converted to a reference type or nullable type.
  • 匿名関数です。An anonymous function. この分類の式は、互換性のあるデリゲート型または式ツリー型に暗黙的に変換できます。An expression with this classification can be implicitly converted to a compatible delegate type or expression tree type.
  • プロパティ アクセス。A property access. すべてのプロパティ アクセスは、関連付けられた型、つまり、プロパティの型を持ちます。Every property access has an associated type, namely the type of the property. さらに、プロパティ アクセスには、関連付けられたインスタンス式があります。Furthermore, a property access may have an associated instance expression. アクセサー (、getまたはsetブロック) のインスタンスのプロパティへのアクセスが呼び出される、インスタンス式の評価の結果によって表されるインスタンスになりますthis(このアクセス)。When an accessor (the get or set block) of an instance property access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access).
  • イベントへのアクセス。An event access. イベントのすべてのアクセスが、関連付けられた型、つまり、イベントの種類。Every event access has an associated type, namely the type of the event. さらに、イベントへのアクセスには、関連付けられたインスタンス式があります。Furthermore, an event access may have an associated instance expression. 左側のオペランドとして、イベントへのアクセスがあります、+=-=演算子 (イベント割り当て)。An event access may appear as the left hand operand of the += and -= operators (Event assignment). 他のコンテキストでは、イベント アクセスとして分類される式は、コンパイル時エラーを発生します。In any other context, an expression classified as an event access causes a compile-time error.
  • インデクサー アクセス。An indexer access. すべてのインデクサー アクセスは、関連付けられた型、インデクサーの要素型つまりを持ちます。Every indexer access has an associated type, namely the element type of the indexer. さらに、インデクサー アクセスは、関連付けられたインスタンス式と、関連する引数リストがいます。Furthermore, an indexer access has an associated instance expression and an associated argument list. アクセサー (、getまたはsetブロック)、インデクサーのアクセスが呼び出される、インスタンス式の評価の結果によって表されるインスタンスになりますthis(このアクセス)、およびの結果引数リストを評価するには、呼び出しのパラメーター リストになります。When an accessor (the get or set block) of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access), and the result of evaluating the argument list becomes the parameter list of the invocation.
  • なし。Nothing. これは、式の戻り値の型には、メソッドの呼び出しは、するときに発生します。voidします。This occurs when the expression is an invocation of a method with a return type of void. コンテキストで有効では何もとして分類される式をstatement_expression (式ステートメント)。An expression classified as nothing is only valid in the context of a statement_expression (Expression statements).

式の最終的な結果は、名前空間、型、メソッド グループ、またはイベントへのアクセスには。The final result of an expression is never a namespace, type, method group, or event access. 代わりに、前述のように、これらの式のカテゴリには特定のコンテキストでのみ許可されている中間的な構造です。Rather, as noted above, these categories of expressions are intermediate constructs that are only permitted in certain contexts.

プロパティ アクセスまたはインデクサーのアクセスは常に再分類を値としての呼び出しを実行することによって、 get アクセサーまたはset アクセサーします。A property access or indexer access is always reclassified as a value by performing an invocation of the get accessor or the set accessor. 特定のアクセサーは、プロパティまたはインデクサーのアクセスのコンテキストによって決まります。アクセスが、割り当ての対象である場合、 set アクセサー新しい値を割り当てるために呼び出される (単純な代入)。The particular accessor is determined by the context of the property or indexer access: If the access is the target of an assignment, the set accessor is invoked to assign a new value (Simple assignment). それ以外の場合、 get アクセサー 、現在の値を取得するために呼び出す (式の値)。Otherwise, the get accessor is invoked to obtain the current value (Values of expressions).

式の値Values of expressions

式を伴う構造のほとんどは最終的に式を表すことを必要とするします。Most of the constructs that involve an expression ultimately require the expression to denote a value. このような場合は、実際の式は、名前空間、型、メソッド グループ、または、何を表す場合、コンパイル時エラーが発生します。In such cases, if the actual expression denotes a namespace, a type, a method group, or nothing, a compile-time error occurs. ただし、式では、プロパティ アクセス、インデクサー アクセス、または変数を表して、プロパティ、インデクサー、または変数の値に暗黙的に代入します。However, if the expression denotes a property access, an indexer access, or a variable, the value of the property, indexer, or variable is implicitly substituted:

  • 変数の値は、変数で識別される記憶域の場所に格納されている値だけです。The value of a variable is simply the value currently stored in the storage location identified by the variable. 変数は、明示的に代入考慮する必要があります (確実な代入) 前に、その値を取得する、またはそれ以外の場合、コンパイル時エラーが発生します。A variable must be considered definitely assigned (Definite assignment) before its value can be obtained, or otherwise a compile-time error occurs.
  • 呼び出して、プロパティ アクセス式の値を取得、 get アクセサープロパティ。The value of a property access expression is obtained by invoking the get accessor of the property. プロパティがにない場合get アクセサーコンパイル時エラーが発生します。If the property has no get accessor, a compile-time error occurs. それ以外の場合、関数メンバーの呼び出し (コンパイル時の動的なオーバー ロードの解決チェック) が実行され、呼び出しの結果、プロパティ アクセス式の値になります。Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed, and the result of the invocation becomes the value of the property access expression.
  • 呼び出してインデクサー アクセス式の値を取得、 get アクセサーのインデクサー。The value of an indexer access expression is obtained by invoking the get accessor of the indexer. インデクサーがにない場合get アクセサーコンパイル時エラーが発生します。If the indexer has no get accessor, a compile-time error occurs. それ以外の場合、関数メンバーの呼び出し (コンパイル時の動的なオーバー ロードの解決チェック) 引数で実行されるインデクサー アクセス式に関連付けられているリストと呼び出しの結果値になりますインデクサー アクセス式。Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed with the argument list associated with the indexer access expression, and the result of the invocation becomes the value of the indexer access expression.

静的および動的バインディングStatic and Dynamic Binding

型または構成する式 (引数、オペランド、受信側) の値に基づく操作の意味を決定するプロセスとして呼ばバインドします。The process of determining the meaning of an operation based on the type or value of constituent expressions (arguments, operands, receivers) is often referred to as binding. たとえば、受信側と引数の型に基づいて、メソッド呼び出しの意味が決まります。For instance the meaning of a method call is determined based on the type of the receiver and arguments. 演算子の意味では、そのオペランドの型に基づいて決定されます。The meaning of an operator is determined based on the type of its operands.

に基づいてその構成要素である式のコンパイル時の型にコンパイル時に、操作の意味が決定されます、通常、c# でします。In C# the meaning of an operation is usually determined at compile-time, based on the compile-time type of its constituent expressions. 同様に、式にエラーが含まれている場合、エラーが検出され、コンパイラによって報告されました。Likewise, if an expression contains an error, the error is detected and reported by the compiler. このアプローチと呼ばれる静的バインディングします。This approach is known as static binding.

ただし、式が動的な式である場合 (つまり、型を持つdynamic) に含まれている任意のバインディングである型ではなくの実行時の型 (つまりの実際の型オブジェクトの実行時にことを示します) に基づく必要があることを示しますこのコンパイル時。However, if an expression is a dynamic expression (i.e. has the type dynamic) this indicates that any binding that it participates in should be based on its run-time type (i.e. the actual type of the object it denotes at run-time) rather than the type it has at compile-time. このような操作のバインディングはそのため、操作がプログラムの実行中に実行時まで延期されます。The binding of such an operation is therefore deferred until the time where the operation is to be executed during the running of the program. 呼ばれる動的バインドします。This is referred to as dynamic binding.

操作が動的にバインドされている場合は、コンパイラによって実行がほとんどまたはまったくないチェックします。When an operation is dynamically bound, little or no checking is performed by the compiler. 代わりに、実行時間のバインドに失敗した場合、実行時に例外としてエラーが報告されます。Instead if the run-time binding fails, errors are reported as exceptions at run-time.

C# では、次の操作は、バインドが適用されます。The following operations in C# are subject to binding:

  • メンバー アクセス。 e.MMember access: e.M
  • メソッドの呼び出し: e.M(e1, ..., eN)Method invocation: e.M(e1, ..., eN)
  • デリゲートの呼び出し:e(e1, ..., eN)Delegate invocation:e(e1, ..., eN)
  • 要素へのアクセス: e[e1, ..., eN]Element access: e[e1, ..., eN]
  • オブジェクトの作成: new C(e1, ..., eN)Object creation: new C(e1, ..., eN)
  • オーバー ロードされた単項演算子: +-!~++--truefalseOverloaded unary operators: +, -, !, ~, ++, --, true, false
  • オーバー ロードされた二項演算子: +-*/%&&&|||??^<<, >>, ==,!=, >, <, >=, <=Overloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=
  • 代入演算子: =+=-=*=/=%=&=|=^=<<=>>=Assignment operators: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • 明示的および暗黙的な変換Implicit and explicit conversions

動的な式が使用されないときに c# 既定値は静的バインディングは、構成する式のコンパイル時の型が、選択プロセスで使用されることを意味します。When no dynamic expressions are involved, C# defaults to static binding, which means that the compile-time types of constituent expressions are used in the selection process. ただし、動的な式は、上記の操作で構成する式のいずれかが、操作は代わりに動的にバインドされます。However, when one of the constituent expressions in the operations listed above is a dynamic expression, the operation is instead dynamically bound.

バインディング時間Binding-time

静的バインディングは、動的バインドが実行時に行いますが、コンパイル時に、配置します。Static binding takes place at compile-time, whereas dynamic binding takes place at run-time. 次のセクションで、用語バインド時コンパイル時または実行時にバインディングが行われる時期に応じてのいずれかを参照します。In the following sections, the term binding-time refers to either compile-time or run-time, depending on when the binding takes place.

次の例は、静的および動的バインディングおよびバインド時の概念を示しています。The following example illustrates the notions of static and dynamic binding and of binding-time:

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引数のコンパイル時の型に基づいて取得されます。The first two calls are statically bound: the overload of Console.WriteLine is picked based on the compile-time type of their argument. したがって、バインド時は、コンパイル時です。Thus, the binding-time is compile-time.

3 番目の呼び出しが動的にバインドされている: のオーバー ロードConsole.WriteLine引数の実行時の型に基づいて取得されます。The third call is dynamically bound: the overload of Console.WriteLine is picked based on the run-time type of its argument. 引数は、動的な式--、コンパイル時の型はdynamicします。This happens because the argument is a dynamic expression -- its compile-time type is dynamic. そのため、3 番目の呼び出しのバインド時は、実行時です。Thus, the binding-time for the third call is run-time.

動的バインディングDynamic binding

動的バインドの目的は、c# プログラムとの対話ができるように、動的オブジェクト、つまり、c# の通常の規則に従っていないオブジェクトがシステムを入力します。The purpose of dynamic binding is to allow C# programs to interact with dynamic objects, i.e. objects that do not follow the normal rules of the C# type system. さまざまな種類のシステムと他のプログラミング言語からオブジェクトを動的オブジェクトがあります。 またはさまざまな操作の独自のバインディング セマンティクスを実装するためにセットアップ プログラムであるオブジェクトがあります。Dynamic objects may be objects from other programming languages with different types systems, or they may be objects that are programmatically setup to implement their own binding semantics for different operations.

動的オブジェクトが自身のセマンティクスを実装するメカニズムは、実装定義です。The mechanism by which a dynamic object implements its own semantics is implementation defined. --もう一度実装定義 - 特定のインターフェイスは、C# で実行時に特別な意味があることを通知する動的オブジェクトによって実装されます。A given interface -- again implementation defined -- is implemented by dynamic objects to signal to the C# run-time that they have special semantics. したがっての動的オブジェクトの操作が動的にバインドされている、ときに、このドキュメントで指定されている c# のではなく、独自のバインディング セマンティクスを引き継ぎます。Thus, whenever operations on a dynamic object are dynamically bound, their own binding semantics, rather than those of C# as specified in this document, take over.

動的バインドの目的は、動的オブジェクトとの相互運用を許可するが、C# では、動的バインド、すべてのオブジェクトでは動的かどうかどうか。While the purpose of dynamic binding is to allow interoperation with dynamic objects, C# allows dynamic binding on all objects, whether they are dynamic or not. これにより、それらに対する操作の結果が、動的なオブジェクト自体ではありませんが、プログラマがコンパイル時に不明な型のままの動的オブジェクトは、スムーズに統合できます。This allows for a smoother integration of dynamic objects, as the results of operations on them may not themselves be dynamic objects, but are still of a type unknown to the programmer at compile-time. 動的バインドが含まれるオブジェクトには、動的オブジェクトがない場合でも、リフレクション ベースのエラーを起こしやすいコードを排除を支援することができます。Also dynamic binding can help eliminate error-prone reflection-based code even when no objects involved are dynamic objects.

動的バインドを適用した場合、何のコンパイル時のチェック - - いずれかが適用される場合と、どのようなコンパイル結果と式分類が正確には、言語では、各構成要素の次のセクションでは、について説明します。The following sections describe for each construct in the language exactly when dynamic binding is applied, what compile time checking -- if any -- is applied, and what the compile-time result and expression classification is.

構成要素である式の種類Types of constituent expressions

操作が静的にバインドされている場合 (例: 受信側、引数、インデックスまたはオペランド) の構成要素である式の型は常と見なされますその式のコンパイル時の型。When an operation is statically bound, the type of a constituent expression (e.g. a receiver, an argument, an index or an operand) is always considered to be the compile-time type of that expression.

操作が動的にバインドされている場合は、構成要素である式のコンパイル時の型に応じてさまざまな方法で構成要素である式の型が決定されます。When an operation is dynamically bound, the type of a constituent expression is determined in different ways depending on the compile-time type of the constituent expression:

  • コンパイル時の型の構成要素である式dynamic式は、実行時に評価されます実際の値の型を持つと見なされます。A constituent expression of compile-time type dynamic is considered to have the type of the actual value that the expression evaluates to at runtime
  • コンパイル時の型は型パラメーターの構成要素である式は実行時に、型パラメーターがバインドされている型であると見なされますA constituent expression whose compile-time type is a type parameter is considered to have the type which the type parameter is bound to at runtime
  • それ以外の場合、構成要素である式は、コンパイル時の型であると見なされます。Otherwise the constituent expression is considered to have its compile-time type.

演算子Operators

式がから構築されたオペランド演算子します。Expressions are constructed from operands and operators. 式の演算子は、オペランドに適用する演算を表します。The operators of an expression indicate which operations to apply to the operands. 演算子の例として、+-*/、および new などがあります。Examples of operators include +, -, *, /, and new. オペランドの例としては、リテラル、フィールド、ローカル変数、式などがあります。Examples of operands include literals, fields, local variables, and expressions.

演算子の 3 つの種類があります。There are three kinds of operators:

  • 単項演算子。Unary operators. 単項演算子が 1 つのオペランドを受け取り、いずれかのプレフィックス表記を使用して (よう--x) または notation の後置 (などx++)。The unary operators take one operand and use either prefix notation (such as --x) or postfix notation (such as x++).
  • 二項演算子。Binary operators. 二項演算子が 2 つのオペランドを取るし、挿入辞表記を使用して、すべて (などx + y)。The binary operators take two operands and all use infix notation (such as x + y).
  • 三項演算子。Ternary operator. 1 つだけの三項演算子?:が存在する 3 つのオペランドを受け取るし、挿入辞表記を使用して (c ? x : y)。Only one ternary operator, ?:, exists; it takes three operands and uses infix notation (c ? x : y).

式の演算子の評価の順序が続く、優先順位結合規則演算子の (演算子の優先順位と結合規則).The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators (Operator precedence and associativity).

式のオペランドは、左から右に評価されます。Operands in an expression are evaluated from left to right. たとえば、 F(i) + G(i++) * H(i)、メソッドFの古い値を使用して呼び出されたi、then メソッドGの古い値を使用して呼び出したi、および、最後に、メソッドHの新しい値を使用して呼び出したi.For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. 演算子の優先順位とは別と関連付けられていないではありません。This is separate from and unrelated to operator precedence.

特定の演算子を指定できますオーバー ロードされたします。Certain operators can be overloaded. 演算子のオーバー ロードは、1 つの操作に対して指定するユーザー定義演算子の実装を許可またはユーザー定義のクラスまたは構造体型の両方のオペランドは (演算子のオーバー ロード)。Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type (Operator overloading).

演算子の優先順位と結合規則Operator precedence and associativity

複数の演算子を含む式の場合、演算子の優先順位によって各々の演算子が評価される順序が決定されます。When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. たとえば、式x + y * zとして評価されますx + (y * z)ため、*演算子は、バイナリよりも優先順位の高い+演算子。For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the binary + operator. 演算子の優先順位は、その関連する文法の運用環境の定義によって確立されます。The precedence of an operator is established by the definition of its associated grammar production. たとえば、 additive_expressionのシーケンスから成るmultiplicative_expressionで区切られた s+または-ため、演算子、+-演算子よりも優先順位を下げる、 */、および%演算子。For example, an additive_expression consists of a sequence of multiplicative_expressions separated by + or - operators, thus giving the + and - operators lower precedence than the *, /, and % operators.

次の表は、優先順位の高いものから最下位の順序ですべての演算子をまとめたものです。The following table summarizes all operators in order of precedence from highest to lowest:

セクションSection カテゴリCategory 演算子Operators
一次式Primary expressions 1 次式Primary x.y f(x) a[x] x++ x-- new typeof default checked unchecked delegatex.y f(x) a[x] x++ x-- new typeof default checked unchecked delegate
単項演算子Unary operators 単項Unary + - ! ~ ++x --x (T)x+ - ! ~ ++x --x (T)x
算術演算子Arithmetic operators 乗法Multiplicative * / %* / %
算術演算子Arithmetic operators 加法Additive + -+ -
シフト演算子Shift operators シフトShift << >><< >>
関係演算子と型検査演算子Relational and type-testing operators 関係式と型検査Relational and type testing < > <= >= is as< > <= >= is as
関係演算子と型検査演算子Relational and type-testing operators 等価比較Equality == !=== !=
論理演算子Logical operators 論理 ANDLogical AND &
論理演算子Logical operators 論理 XORLogical XOR ^
論理演算子Logical operators 論理 ORLogical OR |
条件論理演算子Conditional logical operators 条件 ANDConditional AND &&
条件論理演算子Conditional logical operators 条件 ORConditional OR ||
null 合体演算子The null coalescing operator Null 合体演算子Null coalescing ??
条件演算子Conditional operator 条件Conditional ?:
代入演算子匿名関数式Assignment operators, Anonymous function expressions 代入式とラムダ式Assignment and lambda expression = *= /= %= += -= <<= >>= &= ^= |= =>= *= /= %= += -= <<= >>= &= ^= |= =>

優先順位が同じ 2 つの演算子のオペランドが発生したときに、演算子の結合規則操作が実行される順序を制御します。When an operand occurs between two operators with the same precedence, the associativity of the operators controls the order in which the operations are performed:

  • すべてのバイナリ演算子は、代入演算子と null 合体演算子を除く左結合、左から右に操作を実行することを意味します。Except for the assignment operators and the null coalescing operator, all binary operators are left-associative, meaning that operations are performed from left to right. たとえば、x + y + z(x + y) + z と評価されます。For example, x + y + z is evaluated as (x + y) + z.
  • 代入演算子、null 合体演算子と条件演算子 (?:) は右から左、つまり演算は右から左に実行されます。The assignment operators, the null coalescing operator and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. たとえば、x = y = zx = (y = z) と評価されます。For example, x = y = z is evaluated as x = (y = z).

優先順位と結合性は、かっこを使用して制御することができます。Precedence and associativity can be controlled using parentheses. たとえば、x + y * z は最初に yz を掛け、そして結果を x に足しますが、(x + y) * z では最初に xy を足してから z を掛けます。For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z.

演算子のオーバーロードOperator overloading

すべての単項および二項演算子には定義済みの実装では、任意の式で自動的に利用可能があります。All unary and binary operators have predefined implementations that are automatically available in any expression. 定義済みの実装だけでなくユーザー定義の実装を導入できますoperatorクラスと構造体の宣言 (演算子)。In addition to the predefined implementations, user-defined implementations can be introduced by including operator declarations in classes and structs (Operators). ユーザー定義演算子の実装に常に優先定義済みの演算子の実装。該当するユーザー定義演算子の実装には存在しない場合、定義済みの演算子の実装と見なされるで説明されている専用単項演算子のオーバー ロードの解決二項演算子のオーバー ロード解像度します。User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered, as described in Unary operator overload resolution and Binary operator overload resolution.

オーバー ロードされた単項演算子は。The overloadable unary operators are:

+   -   !   ~   ++   --   true   false

truefalse式で明示的に使用されていない (そのため、優先順位表では含まれませんと演算子の優先順位と結合規則)、いるため、演算子と見なされますいくつかの式のコンテキストで呼び出される: ブール式 (ブール式) と、条件式を含む式 (条件演算子)、および論理条件演算子 (条件付き論理演算子)。Although true and false are not used explicitly in expressions (and therefore are not included in the precedence table in Operator precedence and associativity), they are considered operators because they are invoked in several expression contexts: boolean expressions (Boolean expressions) and expressions involving the conditional (Conditional operator), and conditional logical operators (Conditional logical operators).

二項演算子のオーバー ロード可能なは。The overloadable binary operators are:

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

上記の演算子のみをオーバー ロードできます。Only the operators listed above can be overloaded. 具体的には、メンバー アクセスは、メソッドの呼び出しのオーバー ロードすることはできませんまたは=&&||???:=>checkeduncheckednewtypeofdefaultas、およびis演算子。In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ??, ?:, =>, checked, unchecked, new, typeof, default, as, and is operators.

二項演算子をオーバーロードすると、対応する代入演算子がある場合、これも暗黙的にオーバーロードされます。When a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded. 演算子のオーバー ロードではたとえば、*演算子のオーバー ロードも*=します。For example, an overload of operator * is also an overload of operator *=. 詳細についてはこの複合代入します。This is described further in Compound assignment. なお、代入演算子自体 (=) オーバー ロードできません。Note that the assignment operator itself (=) cannot be overloaded. 常に割り当てでは、変数に値の単純なビットごとのコピーを実行します。An assignment always performs a simple bit-wise copy of a value into a variable.

キャスト演算など(T)x、ユーザー定義の変換を提供することではオーバー ロード (ユーザー定義の変換)。Cast operations, such as (T)x, are overloaded by providing user-defined conversions (User-defined conversions).

要素にアクセスするようa[x]、オーバー ロードされた演算子とは見なされません。Element access, such as a[x], is not considered an overloadable operator. 代わりに、インデクサーによってサポートがユーザー定義のインデックス作成 (インデクサー)。Instead, user-defined indexing is supported through indexers (Indexers).

式では、演算子が演算子の表記を使用して参照されているし、機能の表記を使用して、宣言で演算子が参照されます。In expressions, operators are referenced using operator notation, and in declarations, operators are referenced using functional notation. 次の表では、演算子と単項および二項演算子関数の表記の間の関係を示します。The following table shows the relationship between operator and functional notations for unary and binary operators. 最初のエントリでopプレフィックスのオーバー ロードされた単項演算子を表します。In the first entry, op denotes any overloadable unary prefix operator. 2 番目のエントリでop単項後置形式を表します++--演算子。In the second entry, op denotes the unary postfix ++ and -- operators. 3 番目のエントリでopオーバー ロード可能な 2 項演算子を表します。In the third entry, op denotes any overloadable binary operator.

演算子表記Operator notation 機能の表記Functional notation
op x operator op(x)
x op operator op(x)
x op y operator op(x,y)

ユーザー定義演算子の宣言では、少なくとも 1 つのパラメーターは、演算子の宣言を含むクラスまたは構造体の型が常に要求します。User-defined operator declarations always require at least one of the parameters to be of the class or struct type that contains the operator declaration. したがって、定義済みの演算子と同じシグネチャを持つユーザー定義演算子のことはできません。Thus, it is not possible for a user-defined operator to have the same signature as a predefined operator.

ユーザー定義演算子の宣言には、構文、優先順位、または演算子の結合規則を変更できません。User-defined operator declarations cannot modify the syntax, precedence, or associativity of an operator. たとえば、/演算子は常に二項演算子では、常には、優先順位レベルで指定演算子の優先順位と結合規則、左からの結合は常にします。For example, the / operator is always a binary operator, always has the precedence level specified in Operator precedence and associativity, and is always left-associative.

どのような計算を実行するユーザー定義演算子のことはできますが、直感的に予想されるもの以外の結果を生成するための実装は使用しないでください。While it is possible for a user-defined operator to perform any computation it pleases, implementations that produce results other than those that are intuitively expected are strongly discouraged. 実装ではたとえば、 operator == 2 つのオペランドが等しいかどうかを比較し、適切なを返す必要がありますbool結果。For example, an implementation of operator == should compare the two operands for equality and return an appropriate bool result.

個々 の演算子の説明については、一次式を通じて条件付き論理演算子演算子および適用される追加の規則の定義済みの実装を指定します。それぞれの演算子。The descriptions of individual operators in Primary expressions through Conditional logical operators specify the predefined implementations of the operators and any additional rules that apply to each operator. 説明の用語を使用して、単項演算子のオーバー ロードの解決二項演算子のオーバー ロードの解決、および数値プロモーションは他の定義次のセクションでは、記載されています。The descriptions make use of the terms unary operator overload resolution, binary operator overload resolution, and numeric promotion, definitions of which are found in the following sections.

単項演算子のオーバー ロードの解決Unary operator overload resolution

フォームの操作をop xまたはx opここで、opオーバー ロードされた単項演算子、およびx型の式は、 X、次のように処理されます。An operation of the form op x or x op, where op is an overloadable unary operator, and x is an expression of type X, is processed as follows:

  • 一連の候補ユーザー定義の演算子によって提供されるX操作operator op(x)の規則を使用して決定されます候補ユーザー定義演算子します。The set of candidate user-defined operators provided by X for the operation operator op(x) is determined using the rules of Candidate user-defined operators.
  • ユーザー定義演算子の候補のセットが空でない場合は、この操作の演算子の候補のセットをなります。If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. それ以外の場合、定義済みの単項operator opがリフトのフォームを含めて、実装操作の演算子の候補の集合になります。Otherwise, the predefined unary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. 特定の演算子の定義済みの実装が演算子の説明で指定されます (一次式単項演算子)。The predefined implementations of a given operator are specified in the description of the operator (Primary expressions and Unary operators).
  • オーバー ロード解決規則オーバー ロードの解決引数リストに対して最適な演算子を選択する演算子を候補のセットに適用される(x)、この演算子のオーバー ロードの結果になります解決プロセスです。The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x), and this operator becomes the result of the overload resolution process. 1 つの最適な演算子を選択するオーバー ロードの解決に失敗した場合、バインド時のエラーが発生します。If overload resolution fails to select a single best operator, a binding-time error occurs.

二項演算子のオーバー ロードの解決Binary operator overload resolution

フォームの操作をx op yここで、 op 、オーバー ロードされた二項演算子は、x型の式は、 X、およびy型の式は、 Y、次のように処理されます。An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows:

  • 一連の候補ユーザー定義の演算子によって提供されるXY操作operator op(x,y)決定されます。The set of candidate user-defined operators provided by X and Y for the operation operator op(x,y) is determined. セットによって提供される演算子の候補の和集合から成るXによって提供される演算子の候補とYそれぞれ特定の規則を使用して、候補ユーザー定義演算子します。The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of Candidate user-defined operators. 場合XYは同じ型の場合、またはXY演算子候補、結合されたセットで 1 回しか発生し、共通の基本型から派生します。If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once.
  • ユーザー定義演算子の候補のセットが空でない場合は、この操作の演算子の候補のセットをなります。If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. それ以外の場合、定義済みのバイナリoperator opがリフトのフォームを含めて、実装操作の演算子の候補の集合になります。Otherwise, the predefined binary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. 特定の演算子の定義済みの実装が演算子の説明で指定されます (算術演算子を通じて条件付き論理演算子)。The predefined implementations of a given operator are specified in the description of the operator (Arithmetic operators through Conditional logical operators). 定義済みの列挙型とデリゲートの演算子と見なされる演算子のみでは、オペランドの 1 つのバインド時の型である列挙型、またはデリゲートの型で定義されています。For predefined enum and delegate operators, the only operators considered are those defined by an enum or delegate type that is the binding-time type of one of the operands.
  • オーバー ロード解決規則オーバー ロードの解決引数リストに対して最適な演算子を選択する演算子を候補のセットに適用される(x,y)、この演算子のオーバー ロードの結果になります解決プロセスです。The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x,y), and this operator becomes the result of the overload resolution process. 1 つの最適な演算子を選択するオーバー ロードの解決に失敗した場合、バインド時のエラーが発生します。If overload resolution fails to select a single best operator, a binding-time error occurs.

ユーザー定義演算子の候補Candidate user-defined operators

型を指定してTと操作operator op(A)ここで、opオーバー ロードされた演算子とA引数リストを候補のセットによって提供されるユーザー定義の演算子は、Toperator op(A)決定されます次のようにします。Given a type T and an operation operator op(A), where op is an overloadable operator and A is an argument list, the set of candidate user-defined operators provided by T for operator op(A) is determined as follows:

  • 種類を決定T0します。Determine the type T0. 場合Tが null 許容型では、T0基になる型をそれ以外の場合はT0と等しいTします。If T is a nullable type, T0 is its underlying type, otherwise T0 is equal to T.
  • すべてのoperator op内の宣言T0と少なくとも 1 つの演算子が適用可能な場合は、すべてのリフトのような演算子では、形式 (適用可能な関数メンバー) 引数リストに対してAのセットでは、演算子の候補のような該当するすべての演算子から成るT0します。For all operator op declarations in T0 and all lifted forms of such operators, if at least one operator is applicable (Applicable function member) with respect to the argument list A, then the set of candidate operators consists of all such applicable operators in T0.
  • の場合T0object、演算子の候補のセットが空です。Otherwise, if T0 is object, the set of candidate operators is empty.
  • によって提供される演算子の候補のセットの場合は、T0の直接の基本クラスによって提供される演算子の候補のセットは、 T0、または有効な基本クラスのT0場合T0型パラメーターします。Otherwise, the set of candidate operators provided by T0 is the set of candidate operators provided by the direct base class of T0, or the effective base class of T0 if T0 is a type parameter.

数値の上位変換Numeric promotions

数値の上位変換は、定義済みの単項および二項の数値演算子のオペランドの特定の暗黙的な変換を自動的に実行するので構成されます。Numeric promotion consists of automatically performing certain implicit conversions of the operands of the predefined unary and binary numeric operators. 数値の上位変換はなく、個別のメカニズムではなく、定義済みの演算子をオーバー ロードの解決を適用する効果です。Numeric promotion is not a distinct mechanism, but rather an effect of applying overload resolution to the predefined operators. 数値の上位変換具体的には影響しませんユーザー定義の演算子の評価のような影響が発生するユーザー定義演算子を実装することができます。Numeric promotion specifically does not affect evaluation of user-defined operators, although user-defined operators can be implemented to exhibit similar effects.

数値の上位変換の例は、としては、定義済みのバイナリの実装を考えてみましょう。*演算子。As an example of numeric promotion, consider the predefined implementations of the binary * operator:

int operator *(int x, int y);
uint operator *(uint x, uint 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);

ときにオーバー ロードの解決ルール (オーバー ロードの解決) このセットに適用される演算子の結果はオペランドの型から最初の暗黙的な変換が存在する演算子を選択します。When overload resolution rules (Overload resolution) are applied to this set of operators, the effect is to select the first of the operators for which implicit conversions exist from the operand types. 操作の例では、b * sここで、bは、bytesは、 short、オーバー ロードの解決方法の選択operator *(int,int)最善の演算子として。For example, for the operation b * s, where b is a byte and s is a short, overload resolution selects operator *(int,int) as the best operator. そのため、効果はbsに変換されますint、および結果の型はintします。Thus, the effect is that b and s are converted to int, and the type of the result is int. 同様に、操作のi * dここで、iは、intdは、 double、オーバー ロードの解決方法の選択operator *(double,double)最善の演算子として。Likewise, for the operation i * d, where i is an int and d is a double, overload resolution selects operator *(double,double) as the best operator.

単項の数値の上位変換Unary numeric promotions

定義済みのオペランドの単項の数値の昇格が発生した+-、および~単項演算子。Unary numeric promotion occurs for the operands of the predefined +, -, and ~ unary operators. 単項の数値の上位変換は、型のオペランドを変換するだけで構成されるsbytebyteshortushort、またはchar入力intします。Unary numeric promotion simply consists of converting operands of type sbyte, byte, short, ushort, or char to type int. さらに、単項の-演算子、単項の数値の上位変換型のオペランドの変換uint入力longします。Additionally, for the unary - operator, unary numeric promotion converts operands of type uint to type long.

バイナリ数値プロモーションBinary numeric promotions

定義済みのオペランドのバイナリ数値昇格が発生した+-*/%&|^==!=><>=、および<=二項演算子。Binary numeric promotion occurs for the operands of the predefined +, -, *, /, %, &, |, ^, ==, !=, >, <, >=, and <= binary operators. バイナリ数値の上位変換は、非リレーショナルの演算子が発生した場合、操作の結果の型にもなりますが、共通の型に暗黙的に両方のオペランドを変換します。Binary numeric promotion implicitly converts both operands to a common type which, in case of the non-relational operators, also becomes the result type of the operation. 数値のバイナリの上位変換は、ここに表示される順序で、次の規則を適用することで構成されます。Binary numeric promotion consists of applying the following rules, in the order they appear here:

  • いずれかのオペランドの型の場合decimal、もう一方のオペランドを型に変換されますdecimal、バインド時のエラーは、もう一方のオペランドの型の場合に発生します。 またはfloatまたはdoubleします。If either operand is of type decimal, the other operand is converted to type decimal, or a binding-time error occurs if the other operand is of type float or double.
  • それ以外の場合、いずれかのオペランドの型の場合double、もう一方のオペランドを型に変換されますdoubleします。Otherwise, if either operand is of type double, the other operand is converted to type double.
  • それ以外の場合、いずれかのオペランドの型の場合float、もう一方のオペランドを型に変換されますfloatします。Otherwise, if either operand is of type float, the other operand is converted to type float.
  • それ以外の場合、いずれかのオペランドの型の場合ulong、もう一方のオペランドを型に変換されますulong、バインド時のエラーは、もう一方のオペランドの型の場合に発生します。 またはsbyteshortint、またはlongします。Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
  • それ以外の場合、いずれかのオペランドの型の場合long、もう一方のオペランドを型に変換されますlongします。Otherwise, if either operand is of type long, the other operand is converted to type long.
  • それ以外の場合、いずれかのオペランドの型の場合uintともう一方のオペランド型sbyteshort、またはint、両方のオペランドを型に変換されますlongします。Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
  • それ以外の場合、いずれかのオペランドの型の場合uint、もう一方のオペランドを型に変換されますuintします。Otherwise, if either operand is of type uint, the other operand is converted to type uint.
  • それ以外の場合、両方のオペランドは、型に変換されますintします。Otherwise, both operands are converted to type int.

最初の規則が混在するすべての操作を禁止することに注意してください、decimalの種類をdoublefloat型。Note that the first rule disallows any operations that mix the decimal type with the double and float types. 間の暗黙的な変換がないという事実から、ルールに依存して、decimal型とdoublefloat型。The rule follows from the fact that there are no implicit conversions between the decimal type and the double and float types.

なお、オペランドの型のことはできませんulongもう一方のオペランドが符号付き整数型の場合します。Also note that it is not possible for an operand to be of type ulong when the other operand is of a signed integral type. 理由は、整数型が存在しないことの全範囲を表すことができますulongと符号付き整数型。The reason is that no integral type exists that can represent the full range of ulong as well as the signed integral types.

どちらの場合も、もう一方のオペランドと互換性がある型に 1 つのオペランドを明示的に変換するキャスト式を使用できます。In both of the above cases, a cast expression can be used to explicitly convert one operand to a type that is compatible with the other operand.

In the example

decimal AddPercent(decimal x, double percent) {
    return x * (1.0 + percent / 100.0);
}

バインディング時のエラーが発生、decimalによって乗算することはできません、doubleします。a binding-time error occurs because a decimal cannot be multiplied by a double. 2 番目のオペランドを明示的な変換によって、エラーが解決decimal、次のようにします。The error is resolved by explicitly converting the second operand to decimal, as follows:

decimal AddPercent(decimal x, double percent) {
    return x * (decimal)(1.0 + percent / 100.0);
}

リフトされた演算子Lifted operators

リフト演算子もそれらの型の null 許容のフォームで使用する null 非許容値型を操作する定義済み、ユーザー定義の演算子を許可します。Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. リフトされた演算子は、次の説明に従って特定の要件を満たしている定義済み、ユーザー定義の演算子から構築されます。Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:

  • 単項演算子For the unary operators

    +  ++  -  --  !  ~
    

    場合、オペランドと結果の型は両方が null 非許容値型にリフトされた演算子のフォームが存在します。a lifted form of an operator exists if the operand and result types are both non-nullable value types. リフトの形式が、1 つを追加することで構築された?修飾子をオペランドと結果の型。The lifted form is constructed by adding a single ? modifier to the operand and result types. リフトされた演算子は、オペランドが null の場合、null 値を生成します。The lifted operator produces a null value if the operand is null. それ以外の場合、リフトされた演算子はオペランドのラップを解除し、基になる演算子を適用し、結果をラップします。Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.

  • 2 項演算子For the binary operators

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

    オペランドと結果の型がすべての null 非許容値型である場合、リフトされた演算子のフォームが存在します。a lifted form of an operator exists if the operand and result types are all non-nullable value types. リフトの形式が、1 つを追加することで構築された?オペランドと結果の種類ごとに修飾子。The lifted form is constructed by adding a single ? modifier to each operand and result type. 1 つの場合、リフトされた演算子は null 値を生成または両方のオペランドが null (例外である、&|の演算子、 bool? 」の説明に従って、入力ブール論理演算子)。The lifted operator produces a null value if one or both operands are null (an exception being the & and | operators of the bool? type, as described in Boolean logical operators). それ以外の場合、リフトされた演算子はオペランドのラップを解除し、基になる演算子を適用し、結果をラップします。Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result.

  • 等値演算子のFor the equality operators

    ==  !=
    

    オペランドの型が null 非許容値型と結果型がある場合は、リフトされた演算子のフォームが存在するboolします。a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. リフトの形式が、1 つを追加することで構築された?修飾子を追加します。The lifted form is constructed by adding a single ? modifier to each operand type. リフトされた演算子には、2 つの null 値は等しく、および null 値が null 以外の値に等しくないです。The lifted operator considers two null values equal, and a null value unequal to any non-null value. 両方のオペランドが null 以外の場合は、リフトされた演算子はオペランドのラップを解除しを生成する基になる演算子を適用、bool結果。If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

  • 関係演算子For the relational operators

    <  >  <=  >=
    

    オペランドの型が null 非許容値型と結果型がある場合は、リフトされた演算子のフォームが存在するboolします。a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. リフトの形式が、1 つを追加することで構築された?修飾子を追加します。The lifted form is constructed by adding a single ? modifier to each operand type. リフトされた演算子の値を生成するfalse1 つまたは両方のオペランドが null の場合。The lifted operator produces the value false if one or both operands are null. それ以外の場合、リフトされた演算子はオペランドのラップを解除し、生成するために基になる演算子を適用、bool結果。Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

メンバー ルックアップMember lookup

メンバー検索は、型のコンテキストで名前の意味を決定するというプロセスです。A member lookup is the process whereby the meaning of a name in the context of a type is determined. メンバー参照が評価の一部として発生することが、 simple_name (簡易名) またはmember_access (メンバー アクセス) で、式。A member lookup can occur as part of evaluating a simple_name (Simple names) or a member_access (Member access) in an expression. 場合、 simple_nameまたはmember_accessとして発生する、 primary_expressioninvocation_expression (メソッドの呼び出し)、呼び出されるメンバーと呼びます。If the simple_name or member_access occurs as the primary_expression of an invocation_expression (Method invocations), the member is said to be invoked.

メンバーがメソッドまたはイベントの場合、または定数、フィールド、またはデリゲート型のプロパティである場合 (デリゲート)、または型dynamic(動的な型)、メンバーはと呼ばれますし、invocableします。If a member is a method or event, or if it is a constant, field or property of either a delegate type (Delegates) or the type dynamic (The dynamic type), then the member is said to be invocable.

メンバー参照では、メンバーが型パラメーターと、メンバーがアクセスできるかどうかの数が、メンバーの名前だけでなくと見なします。Member lookup considers not only the name of a member but also the number of type parameters the member has and whether the member is accessible. メンバー検索のためには、それぞれの宣言に示されている型パラメーターの数であるジェネリック メソッドと入れ子になったジェネリック型とその他のすべてのメンバーは、0 個の型パラメーターを指定します。For the purposes of member lookup, generic methods and nested generic types have the number of type parameters indicated in their respective declarations and all other members have zero type parameters.

名前のメンバー検索 NK 型にパラメーターを入力 Tように処理されます。A member lookup of a name N with K type parameters in a type T is processed as follows:

  • 最初に、アクセス可能なメンバーがという名前のセットを N決定されます。First, a set of accessible members named N is determined:
    • 場合T、型パラメーター セットがアクセス可能なメンバーがという名前のセットの和集合が N制約のプライマリまたはセカンダリの制約として指定された型の各 (パラメーターの制約入力) の T、アクセス可能なメンバーがという名前のセットと共に Nobjectします。If T is a type parameter, then the set is the union of the sets of accessible members named N in each of the types specified as a primary constraint or secondary constraint (Type parameter constraints) for T, along with the set of accessible members named N in object.
    • それ以外の場合、すべてにアクセスできるのセットが (メンバー アクセス) という名前のメンバー Nで T継承されたメンバーと名前付きアクセス可能なメンバーを含めて、 Nobjectします。Otherwise, the set consists of all accessible (Member access) members named N in T, including inherited members and the accessible members named N in object. 場合T構築された型は、メンバーのセットが」の説明に従って、型引数を代入することによって取得した構築された型のメンバーします。If T is a constructed type, the set of members is obtained by substituting type arguments as described in Members of constructed types. メンバーが含まれる、override修飾子は、セットから除外されます。Members that include an override modifier are excluded from the set.
  • 次に、ifKは 0、型の宣言には、型パラメーターが含まれては削除が入れ子になったすべてです。Next, if K is zero, all nested types whose declarations include type parameters are removed. 場合K、異なる数のパラメーターを削除する型を持つすべてのメンバーに 0 以外です。If K is not zero, all members with a different number of type parameters are removed. 場合Kが 0 個、メソッドのある型の型の推論プロセス以降のパラメーターは削除されません (型推論) 型引数の推論できる場合があります。Note that when K is zero, methods having type parameters are not removed, since the type inference process (Type inference) might be able to infer the type arguments.
  • 次に、メンバーがある場合呼び出さ、以外のすべて-invocableメンバーをセットから削除します。Next, if the member is invoked, all non-invocable members are removed from the set.
  • 次に、他のメンバーが隠ぺいされているメンバーは、セットから削除されます。Next, members that are hidden by other members are removed from the set. すべてのメンバーのS.M、セット内でSの種類は、メンバー M宣言されると、次の規則が適用されます。For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied:
    • 場合Mの基本型で宣言されているすべてのメンバー、定数、フィールド、プロパティ、イベント、または列挙型のメンバーは、Sセットから削除されます。If M is a constant, field, property, event, or enumeration member, then all members declared in a base type of S are removed from the set.
    • 場合Mが型の宣言型以外のすべての基本型で宣言されたS、セットから削除はすべて、同じ数と型パラメーターの宣言型とMの基本型で宣言されたSが削除されますセット。If M is a type declaration, then all non-types declared in a base type of S are removed from the set, and all type declarations with the same number of type parameters as M declared in a base type of S are removed from the set.
    • 場合M、メソッドの基本型で宣言されているすべてのメソッド以外のメンバーがSセットから削除されます。If M is a method, then all non-method members declared in a base type of S are removed from the set.
  • 次に、クラス メンバーが隠ぺいされているインターフェイス メンバーは、セットから削除されます。Next, interface members that are hidden by class members are removed from the set. ここでは、場合にのみT型パラメーターとT以外の両方を有効な基本クラスを持つobjectと空でない有効なインターフェイス セット (パラメーターの制約入力)。This step only has an effect if T is a type parameter and T has both an effective base class other than object and a non-empty effective interface set (Type parameter constraints). すべてのメンバーのS.M、セット内でSの種類は、メンバーMが宣言されている場合に、次の規則が適用されるS以外のクラス宣言は、 object:For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied if S is a class declaration other than object:
    • 場合Mが定数、フィールド、プロパティ、イベント、列挙型メンバー、または型の宣言、インターフェイス宣言で宣言されているすべてのメンバーは、セットから削除されます。If M is a constant, field, property, event, enumeration member, or type declaration, then all members declared in an interface declaration are removed from the set.
    • 場合M、インターフェイス宣言で宣言されているすべてのメソッド以外のメンバーは、セット、およびと同じシグネチャを持つすべてのメソッドから削除されますが、メソッド、M宣言インターフェイスの宣言は、セットから削除されます。If M is a method, then all non-method members declared in an interface declaration are removed from the set, and all methods with the same signature as M declared in an interface declaration are removed from the set.
  • 最後に、非表示のメンバーを削除すると、検索の結果が決定されます。Finally, having removed hidden members, the result of the lookup is determined:
    • セット メソッドではない 1 つのメンバーの場合、このメンバーは、参照の結果です。If the set consists of a single member that is not a method, then this member is the result of the lookup.
    • それ以外の場合、セットにメソッドのみが含まれている場合、参照の結果はメソッドのこのグループにします。Otherwise, if the set contains only methods, then this group of methods is the result of the lookup.
    • それ以外の場合、参照があいまいであり、バインド エラーが発生します。Otherwise, the lookup is ambiguous, and a binding-time error occurs.

型パラメーターとのインターフェイス以外の型のメンバーの検索と厳密な単一継承インターフェイス メンバーの検索 (継承チェーン内の各インターフェイスが厳密に 0 個または 1 つの直接基底インターフェイス)、参照ルールの影響は、同じ名前またはシグネチャを持つメンバーの非表示にする基本メンバーを派生するだけです。For member lookups in types other than type parameters and interfaces, and member lookups in interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature. このような単一継承の参照があいまいなことはできません。Such single-inheritance lookups are never ambiguous. 多重継承インターフェイス メンバー検索から発生する可能性のあいまいさが記載されてインターフェイス メンバーへのアクセスします。The ambiguities that can possibly arise from member lookups in multiple-inheritance interfaces are described in Interface member access.

基本データ型Base types

メンバーの検索、一種の目的でT次の基本型を持つと見なされます。For purposes of member lookup, a type T is considered to have the following base types:

  • 場合Tobject、しT基本データ型がありません。If T is object, then T has no base type.
  • 場合Tは、 enum_typeの基本型Tクラス型であるSystem.EnumSystem.ValueType、およびobjectします。If T is an enum_type, the base types of T are the class types System.Enum, System.ValueType, and object.
  • 場合Tは、 struct_typeの基本型Tクラス型であるSystem.ValueTypeobjectします。If T is a struct_type, the base types of T are the class types System.ValueType and object.
  • 場合Tは、 class_typeの基本型Tの基本クラスT、クラス型を含むobjectします。If T is a class_type, the base types of T are the base classes of T, including the class type object.
  • 場合Tは、 interface_typeの基本型Tの基本インターフェイスTクラス型とobjectします。If T is an interface_type, the base types of T are the base interfaces of T and the class type object.
  • 場合Tは、 array_typeの基本型Tクラス型であるSystem.Arrayobjectします。If T is an array_type, the base types of T are the class types System.Array and object.
  • 場合Tは、 delegate_typeの基本型Tクラス型であるSystem.Delegateobjectします。If T is a delegate_type, the base types of T are the class types System.Delegate and object.

関数メンバーFunction members

関数メンバーは、実行可能なステートメントが含まれているメンバーです。Function members are members that contain executable statements. 関数メンバーは型のメンバーでは常に、名前空間のメンバーであることはできません。Function members are always members of types and cannot be members of namespaces. C# 関数メンバーの次のカテゴリを定義します。C# defines the following categories of function members:

  • メソッドMethods
  • プロパティProperties
  • イベントEvents
  • インデクサーIndexers
  • ユーザー定義演算子User-defined operators
  • インスタンス コンス トラクターInstance constructors
  • 静的コンストラクターStatic constructors
  • デストラクターDestructors

デストラクター (これは、明示的に呼び出すことはできません)、静的コンス トラクターを除く、関数メンバーに含まれているステートメントは、関数メンバーの呼び出しを通じて実行されます。Except for destructors and static constructors (which cannot be invoked explicitly), the statements contained in function members are executed through function member invocations. 関数メンバーの呼び出しを記述するための実際の構文は、特定の関数メンバーのカテゴリに依存します。The actual syntax for writing a function member invocation depends on the particular function member category.

引数リスト (引数リスト) 関数メンバーの呼び出しでは、実際の値または変数参照、関数メンバーのパラメーター。The argument list (Argument lists) of a function member invocation provides actual values or variable references for the parameters of the function member.

ジェネリック メソッドの呼び出しは、メソッドに渡す型引数のセットを決定する型の推定を採用できます。Invocations of generic methods may employ type inference to determine the set of type arguments to pass to the method. このプロセスについては、「型推論します。This process is described in Type inference.

メソッド、インデクサー、演算子、およびインスタンス コンス トラクターの呼び出しは、候補の関数メンバーを呼び出す一連の判断するためにオーバー ロードの解決を使用します。Invocations of methods, indexers, operators and instance constructors employ overload resolution to determine which of a candidate set of function members to invoke. このプロセスについては、「オーバー ロードの解決します。This process is described in Overload resolution.

バインディング時に特定の関数メンバーを特定したら、可能性があるオーバー ロードの解決、関数メンバーを呼び出して実際の実行時プロセスがで説明されているコンパイル時の動的なオーバー ロードの解決のチェック.Once a particular function member has been identified at binding-time, possibly through overload resolution, the actual run-time process of invoking the function member is described in Compile-time checking of dynamic overload resolution.

次の表では、明示的に呼び出される関数メンバーの 6 つのカテゴリに関連する構成要素で発生する処理をまとめたものです。The following table summarizes the processing that takes place in constructs involving the six categories of function members that can be explicitly invoked. 表に、 exy、およびvalue変数または値として分類される式を示すT型として分類される式を示しますFメソッドをおよびの単純な名前を指定Pプロパティの単純な名前を指定します。In the table, e, x, y, and value indicate expressions classified as variables or values, T indicates an expression classified as a type, F is the simple name of a method, and P is the simple name of a property.

コンス トラクターConstruct Example 説明Description
メソッドの呼び出しMethod invocation F(x,y) 最適な方法を選択するオーバー ロードの解決が適用されるF包含クラスまたは構造体でします。Overload resolution is applied to select the best method F in the containing class or struct. 引数リストを持つメソッドが呼び出される(x,y)します。The method is invoked with the argument list (x,y). メソッドではない場合static、インスタンス式がthisします。If the method is not static, the instance expression is this.
T.F(x,y) 最適な方法を選択するオーバー ロードの解決が適用されるFクラスまたは構造体でTします。Overload resolution is applied to select the best method F in the class or struct T. メソッドではない場合、バインド時のエラーが発生するstaticします。A binding-time error occurs if the method is not static. 引数リストを持つメソッドが呼び出される(x,y)します。The method is invoked with the argument list (x,y).
e.F(x,y) クラス、構造体、またはインターフェイスの型で指定された F の最適な方法を選択するオーバー ロードの解決が適用されるeします。Overload resolution is applied to select the best method F in the class, struct, or interface given by the type of e. メソッドの場合、バインド時のエラーが発生するstaticします。A binding-time error occurs if the method is static. インスタンス式が、このメソッドはeおよび引数リスト(x,y)します。The method is invoked with the instance expression e and the argument list (x,y).
「プロパティ アクセス」Property access P getプロパティのアクセサーP包含クラスまたは構造体でが呼び出されます。The get accessor of the property P in the containing class or struct is invoked. コンパイル時エラーが発生しますPは書き込み専用です。A compile-time error occurs if P is write-only. 場合Pないstatic、インスタンス式がthisします。If P is not static, the instance expression is this.
P = value setプロパティのアクセサーP包含クラスまたは構造体では引数リストによって呼び出される(value)します。The set accessor of the property P in the containing class or struct is invoked with the argument list (value). コンパイル時エラーが発生しますPは読み取り専用です。A compile-time error occurs if P is read-only. 場合Pないstatic、インスタンス式がthisします。If P is not static, the instance expression is this.
T.P getプロパティのアクセサーPクラスまたは構造体でTが呼び出されます。The get accessor of the property P in the class or struct T is invoked. コンパイル時エラーが発生しますPないstatic場合Pは書き込み専用です。A compile-time error occurs if P is not static or if P is write-only.
T.P = value setプロパティのアクセサーPクラスまたは構造体でTが呼び出されると、引数リスト(value)します。The set accessor of the property P in the class or struct T is invoked with the argument list (value). コンパイル時エラーが発生しますPないstatic場合Pは読み取り専用です。A compile-time error occurs if P is not static or if P is read-only.
e.P getプロパティのアクセサーPクラス、構造体、またはインターフェイスの型で指定されたeが呼び出されるインスタンス式とeします。The get accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e. バインディング時のエラーが発生しますPstatic場合Pは書き込み専用です。A binding-time error occurs if P is static or if P is write-only.
e.P = value setプロパティのアクセサーPクラス、構造体、またはインターフェイスの型で指定されたeが呼び出されるインスタンス式とeおよび引数リスト(value)します。The set accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e and the argument list (value). バインディング時のエラーが発生しますPstatic場合Pは読み取り専用です。A binding-time error occurs if P is static or if P is read-only.
イベントへのアクセスEvent access E += value addイベントのアクセサーE包含クラスまたは構造体でが呼び出されます。The add accessor of the event E in the containing class or struct is invoked. 場合Eは静的でないインスタンス式がthisします。If E is not static, the instance expression is this.
E -= value removeイベントのアクセサーE包含クラスまたは構造体でが呼び出されます。The remove accessor of the event E in the containing class or struct is invoked. 場合Eは静的でないインスタンス式がthisします。If E is not static, the instance expression is this.
T.E += value addイベントのアクセサーEクラスまたは構造体でTが呼び出されます。The add accessor of the event E in the class or struct T is invoked. バインディング時のエラーが発生しますEは静的でありません。A binding-time error occurs if E is not static.
T.E -= value removeイベントのアクセサーEクラスまたは構造体でTが呼び出されます。The remove accessor of the event E in the class or struct T is invoked. バインディング時のエラーが発生しますEは静的でありません。A binding-time error occurs if E is not static.
e.E += value addイベントのアクセサーEクラス、構造体、またはインターフェイスの型で指定されたeが呼び出されるインスタンス式とeします。The add accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. バインディング時のエラーが発生しますEは静的です。A binding-time error occurs if E is static.
e.E -= value removeイベントのアクセサーEクラス、構造体、またはインターフェイスの型で指定されたeが呼び出されるインスタンス式とeします。The remove accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. バインディング時のエラーが発生しますEは静的です。A binding-time error occurs if E is static.
インデクサーへのアクセスIndexer access e[x,y] クラス、構造体、または電子メールの種類によって指定されたインターフェイスで最適なインデクサーを選択するのには、オーバー ロードの解決が適用されます。Overload resolution is applied to select the best indexer in the class, struct, or interface given by the type of e. getインスタンス式が、インデクサーのアクセサーが呼び出されるeおよび引数リスト(x,y)します。The get accessor of the indexer is invoked with the instance expression e and the argument list (x,y). インデクサーが書き込み専用の場合は、バインド エラーになります。A binding-time error occurs if the indexer is write-only.
e[x,y] = value クラス、構造体、またはインターフェイスの型で指定された最適なインデクサーを選択するオーバー ロードの解決が適用されるeします。Overload resolution is applied to select the best indexer in the class, struct, or interface given by the type of e. setインスタンス式が、インデクサーのアクセサーが呼び出されるeおよび引数リスト(x,y,value)します。The set accessor of the indexer is invoked with the instance expression e and the argument list (x,y,value). バインディング エラーは、インデクサーは読み取り専用である場合に発生します。A binding-time error occurs if the indexer is read-only.
演算子の呼び出しOperator invocation -x クラスまたは構造体の型で指定されたで最善の単項演算子を選択するオーバー ロードの解決が適用されるxします。Overload resolution is applied to select the best unary operator in the class or struct given by the type of x. 引数リストで選択した演算子が呼び出される(x)します。The selected operator is invoked with the argument list (x).
x + y クラスまたは構造体の型で指定された、最適な二項演算子を選択するオーバー ロードの解決が適用されるxyします。Overload resolution is applied to select the best binary operator in the classes or structs given by the types of x and y. 引数リストで選択した演算子が呼び出される(x,y)します。The selected operator is invoked with the argument list (x,y).
インスタンス コンス トラクターの呼び出しInstance constructor invocation new T(x,y) クラスまたは構造体で最適なインスタンス コンス トラクターを選択するオーバー ロードの解決が適用されるTします。Overload resolution is applied to select the best instance constructor in the class or struct T. インスタンス コンス トラクターが呼び出される引数リストと(x,y)します。The instance constructor is invoked with the argument list (x,y).

引数リストArgument lists

すべての関数メンバーおよびデリゲートの呼び出しには、関数メンバーのパラメーターの実際の値または変数参照を提供する引数リストが含まれています。Every function member and delegate invocation includes an argument list which provides actual values or variable references for the parameters of the function member. 関数メンバーの呼び出しの引数リストを指定する構文は、関数メンバーのカテゴリによって異なります。The syntax for specifying the argument list of a function member invocation depends on the function member category:

  • インスタンスのコンス トラクター、メソッド、インデクサー、およびデリゲートを引数は、 argument_list以下の説明に従って、します。For instance constructors, methods, indexers and delegates, the arguments are specified as an argument_list, as described below. インデクサーの場合を呼び出すときに、setアクセサー、さらに含まれています、代入演算子の右側のオペランドとして指定された式の引数リスト。For indexers, when invoking the set accessor, the argument list additionally includes the expression specified as the right operand of the assignment operator.
  • プロパティについては、引数リストが空を呼び出すときに、getアクセサーを呼び出すときに、代入演算子の右側のオペランドとして指定された式で構成されて、setアクセサー。For properties, the argument list is empty when invoking the get accessor, and consists of the expression specified as the right operand of the assignment operator when invoking the set accessor.
  • 右側のオペランドとして指定された式の引数リストは、イベントの場合、+=または-=演算子。For events, the argument list consists of the expression specified as the right operand of the += or -= operator.
  • ユーザー定義演算子では、引数リストは、単項演算子の 1 つのオペランドまたは二項演算子の 2 つのオペランドで構成されます。For user-defined operators, the argument list consists of the single operand of the unary operator or the two operands of the binary operator.

プロパティの引数 (プロパティ)、イベント (イベント)、およびユーザー定義演算子 (演算子) は、常に値パラメーターとして渡されます (パラメーターの値)。The arguments of properties (Properties), events (Events), and user-defined operators (Operators) are always passed as value parameters (Value parameters). インデクサーの引数 (インデクサー) は、常に値パラメーターとして渡されます (パラメーターの値) またはパラメーターの配列 (パラメーター配列)。The arguments of indexers (Indexers) are always passed as value parameters (Value parameters) or parameter arrays (Parameter arrays). これらの関数メンバーのカテゴリでは、パラメーターの参照を出力パラメーターはサポートされていません。Reference and output parameters are not supported for these categories of function members.

インスタンス コンス トラクター、メソッド、インデクサー、またはデリゲート呼び出しの引数として指定されます、 argument_list:The arguments of an instance constructor, method, indexer or delegate invocation are specified as an argument_list:

argument_list
    : argument (',' argument)*
    ;

argument
    : argument_name? argument_value
    ;

argument_name
    : identifier ':'
    ;

argument_value
    : expression
    | 'ref' variable_reference
    | 'out' variable_reference
    ;

Argument_list 1 つまたは複数から成る引数s、コンマで区切られました。An argument_list consists of one or more arguments, separated by commas. 省略可能なは、各引数argument_name続けて、 argument_valueします。Each argument consists of an optional argument_name followed by an argument_value. 引数で、 argument_nameと呼ばれます、名前付き引数であるのに対し、引数せず、 argument_nameは、位置指定引数します。An argument with an argument_name is referred to as a named argument, whereas an argument without an argument_name is a positional argument. 位置指定引数の名前付き引数の後に表示されるエラーは、 argument_listします。It is an error for a positional argument to appear after a named argument in an argument_list.

Argument_value形式は次のいずれかを実行します。The argument_value can take one of the following forms:

  • を示す値を持つパラメーターとして渡される引数 (パラメーターの値)。An expression, indicating that the argument is passed as a value parameter (Value parameters).
  • キーワードref続けて、 variable_reference (変数参照)、参照パラメーターとして渡される引数を示す (パラメーターを参照).The keyword ref followed by a variable_reference (Variable references), indicating that the argument is passed as a reference parameter (Reference parameters). 変数を明示的に代入する必要があります (確実な代入) 前に、参照パラメーターとして渡すことができます。A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter. キーワードout続けて、 variable_reference (変数参照)、出力パラメーターとして渡される引数を示す (出力パラメーター).The keyword out followed by a variable_reference (Variable references), indicating that the argument is passed as an output parameter (Output parameters). 変数が確実に割り当てられていると見なされます (確実な代入) 次の変数が出力パラメーターとして渡された関数メンバーの呼び出し。A variable is considered definitely assigned (Definite assignment) following a function member invocation in which the variable is passed as an output parameter.

対応するパラメーターCorresponding parameters

引数リストの各引数の関数メンバーまたは呼び出されるデリゲートに対応するパラメーターがあります。For each argument in an argument list there has to be a corresponding parameter in the function member or delegate being invoked.

次で使用されるパラメーターのリストは、次のように決定されます。The parameter list used in the following is determined as follows:

  • 仮想メソッドとクラスで定義されているインデクサーでは、パラメーター リストの最も固有の宣言からピッキングまたは以降で、受信側の静的な型とその基本クラスを検索、関数メンバーのオーバーライドします。For virtual methods and indexers defined in classes, the parameter list is picked from the most specific declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes.
  • パラメーター リストを取得するインターフェイスのメソッドとインデクサーはインターフェイス型で始まると、基本インターフェイスを検索、メンバーの最も固有の定義を形成します。For interface methods and indexers, the parameter list is picked form the most specific definition of the member, starting with the interface type and searching through the base interfaces. 一意のパラメーター リストが見つからないかどうか、アクセスできない名前と省略可能なパラメーターなしのパラメーター リストが構築するための呼び出しが名前付きパラメーターを使用して、または省略可能な引数を省略することはできません。If no unique parameter list is found, a parameter list with inaccessible names and no optional parameters is constructed, so that invocations cannot use named parameters or omit optional arguments.
  • 部分メソッドの定義の部分メソッド宣言のパラメーター リストが使用されます。For partial methods, the parameter list of the defining partial method declaration is used.
  • その他のすべての関数メンバーとデリゲートを使用する 1 つのパラメーター リストだけがあります。For all other function members and delegates there is only a single parameter list, which is the one used.

引数またはパラメーターの位置は、引数または引数のリストまたはパラメーター リスト内の前のパラメーターの数として定義されます。The position of an argument or parameter is defined as the number of arguments or parameters preceding it in the argument list or parameter list.

関数メンバーの引数に対応するパラメーターは、次のように確立されています。The corresponding parameters for function member arguments are established as follows:

  • 引数、 argument_listインスタンス コンス トラクター、メソッド、インデクサー、およびデリゲートの。Arguments in the argument_list of instance constructors, methods, indexers and delegates:
    • パラメーター リスト内の同じ位置に固定のパラメーターが発生した位置指定引数は、そのパラメーターに対応します。A positional argument where a fixed parameter occurs at the same position in the parameter list corresponds to that parameter.
    • 標準形式で呼び出されたパラメーター配列を持つ関数メンバーの位置指定引数は、パラメーター リストの同じ位置にある必要がありますをパラメーター配列に対応します。A positional argument of a function member with a parameter array invoked in its normal form corresponds to the parameter array, which must occur at the same position in the parameter list.
    • 拡張形式、場所、パラメーター リスト内の同じ位置で固定のパラメーターは行われませんで呼び出されたパラメーター配列を持つ関数メンバーの位置指定引数は、パラメーター配列内の要素に対応します。A positional argument of a function member with a parameter array invoked in its expanded form, where no fixed parameter occurs at the same position in the parameter list, corresponds to an element in the parameter array.
    • 名前付き引数は、パラメーター リスト内の同じ名前のパラメーターに対応します。A named argument corresponds to the parameter of the same name in the parameter list.
    • インデクサーの場合を呼び出すときに、setアクセサー、暗黙に対応する代入演算子の右側のオペランドとして指定された式valueのパラメーター、setアクセサーの宣言。For indexers, when invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
  • 呼び出すときに、プロパティのgetありますアクセサーに引数がありません。For properties, when invoking the get accessor there are no arguments. 呼び出すときに、setアクセサー、暗黙に対応する代入演算子の右側のオペランドとして指定された式valueのパラメーター、setアクセサーの宣言。When invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
  • (変換を含む) ユーザー定義の単項演算子の 1 つのオペランドは、演算子の宣言の 1 つのパラメーターに対応します。For user-defined unary operators (including conversions), the single operand corresponds to the single parameter of the operator declaration.
  • 二項演算子のユーザー定義の最初のパラメーターに対応する左のオペランドと右のオペランドが演算子の宣言の 2 番目のパラメーターに対応しています。For user-defined binary operators, the left operand corresponds to the first parameter, and the right operand corresponds to the second parameter of the operator declaration.

引数リストの実行時の評価Run-time evaluation of argument lists

関数メンバーの呼び出しの実行時の処理中に (コンパイル時の動的なオーバー ロードの解決チェック)、式または引数リストの変数の参照として、左から順番に評価されます次に示します。During the run-time processing of a function member invocation (Compile-time checking of dynamic overload resolution), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

  • 引数式の評価の値を持つパラメーター、および暗黙的な変換 (暗黙的な変換) の対応するパラメーター型が実行されます。For a value parameter, the argument expression is evaluated and an implicit conversion (Implicit conversions) to the corresponding parameter type is performed. 結果の値では、関数メンバーの呼び出しで値パラメーターの初期値になります。The resulting value becomes the initial value of the value parameter in the function member invocation.
  • 参照または出力パラメーターの場合は、変数参照が評価され、結果ストレージの場所は、関数メンバーの呼び出しでパラメーターによって表される記憶域の場所になります。For a reference or output parameter, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. 参照または出力パラメーターとして指定された変数の参照の配列要素である場合、 reference_type配列の要素の型がパラメーターの型と同じであることを確認する実行時チェックが行われます。If the variable reference given as a reference or output parameter is an array element of a reference_type, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. このチェックに失敗した場合、System.ArrayTypeMismatchExceptionがスローされます。If this check fails, a System.ArrayTypeMismatchException is thrown.

メソッド、インデクサー、およびインスタンス コンス トラクターはパラメーター配列の最も右にあるパラメーターを宣言できます (パラメーター配列)。Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array (Parameter arrays). このような関数メンバーは、標準形式、またはどちらが該当するによって、拡張の形式で呼び出される (適用可能な関数メンバー)。Such function members are invoked either in their normal form or in their expanded form depending on which is applicable (Applicable function member):

  • パラメーター配列を持つ関数メンバーが、標準形式で呼び出されると、パラメーター配列の指定された引数が暗黙的に変換可能である 1 つの式をある必要があります (暗黙的な変換) に、パラメーター配列の型。When a function member with a parameter array is invoked in its normal form, the argument given for the parameter array must be a single expression that is implicitly convertible (Implicit conversions) to the parameter array type. この場合、パラメーター配列は、値を持つパラメーターとまったく同じように機能します。In this case, the parameter array acts precisely like a value parameter.
  • 拡張形式でパラメーター配列を持つ関数メンバーが呼び出されると、呼び出しがそれぞれの引数が、暗黙的に変換する式は、パラメーター配列の 0 個以上の位置指定引数を指定する必要があります (暗黙の型変換) パラメーターの配列の要素の型にします。When a function member with a parameter array is invoked in its expanded form, the invocation must specify zero or more positional arguments for the parameter array, where each argument is an expression that is implicitly convertible (Implicit conversions) to the element type of the parameter array. ここでは、呼び出し引数の数に対応する長さを持つパラメーターの配列型のインスタンスを作成します。 指定された引数に値を使用して、配列インスタンスの要素を初期化し、実際に新しく作成された配列のインスタンスを使用引数。In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument.

引数リストの式は常に記述されている順序で評価します。The expressions of an argument list are always evaluated in the order they are written. 例では、そのため、Thus, the example

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

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

この例では、次のように出力されます。produces the output

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

配列の共変性規則 (配列の共変性) 配列型の値を許可A[]配列型のインスタンスへの参照であるB[]から暗黙の参照変換が存在する限り、BA.The array co-variance rules (Array covariance) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. 配列の要素のときに、これらの規則のため、 reference_typeが渡される参照または出力パラメーターとして、実行時チェックが配列の実際の要素の型が、パラメーターの場合と同じであることを確認するために必要です。Because of these rules, when an array element of a reference_type is passed as a reference or output parameter, a run-time check is required to ensure that the actual element type of the array is identical to that of the parameter. In the example

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
    }
}

2 番目の呼び出しのFにより、System.ArrayTypeMismatchExceptionが、実際の要素の入力のためにスローされるbstringおよび not objectthe second invocation of F causes a System.ArrayTypeMismatchException to be thrown because the actual element type of b is string and not object.

場合と同様、配列初期化子で配列作成式拡張形式でパラメーター配列を持つ関数メンバーが呼び出されると、呼び出しは処理されます (配列作成式) 周囲に挿入されて、拡張パラメーター。When a function member with a parameter array is invoked in its expanded form, the invocation is processed exactly as if an array creation expression with an array initializer (Array creation expressions) was inserted around the expanded parameters. たとえば、宣言について考えます。For example, given the declaration

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

メソッドの拡張形式の次の呼び出しthe following invocations of the expanded form of the method

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

正確に対応していますcorrespond exactly to

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

具体的には、パラメーター配列の指定された 0 個の引数がある場合、空の配列が作成されたことに注意してください。In particular, note that an empty array is created when there are zero arguments given for the parameter array.

対応する省略可能なパラメーターを持つ関数メンバーからは、引数が省略された場合、関数メンバー宣言の既定の引数は暗黙的に渡されます。When arguments are omitted from a function member with corresponding optional parameters, the default arguments of the function member declaration are implicitly passed. これらの定数は常に、ための評価は、残りの引数の評価順序は影響しません。Because these are always constant, their evaluation will not impact the evaluation order of the remaining arguments.

型の推論Type inference

型引数を指定せずにジェネリック メソッドが呼び出されたときに、型推論プロセスは呼び出しの引数の型を推論しようとしています。When a generic method is called without specifying type arguments, a type inference process attempts to infer type arguments for the call. 型の推定の存在は、ジェネリック メソッドの呼び出しに使用する便利な構文を使用でき、プログラマの冗長の種類の情報を指定することを回避するためにです。The presence of type inference allows a more convenient syntax to be used for calling a generic method, and allows the programmer to avoid specifying redundant type information. たとえば、メソッドの宣言を考えてみます。For example, given the method declaration:

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

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

呼び出すことは、Choose型引数を明示的に指定しないでメソッド。it is possible to invoke the Choose method without explicitly specifying a type argument:

int i = Chooser.Choose(5, 213);                 // Calls Choose<int>

string s = Chooser.Choose("foo", "bar");        // Calls Choose<string>

型推論、型引数を通じてintstringメソッドに引数から決定されます。Through type inference, the type arguments int and string are determined from the arguments to the method.

メソッドの呼び出しのバインド時の処理の一部として型の推定が発生します (メソッドの呼び出し) と前の呼び出しのオーバー ロードの解決手順に、を実施します。Type inference occurs as part of the binding-time processing of a method invocation (Method invocations) and takes place before the overload resolution step of the invocation. 特定のメソッドのグループがメソッドの呼び出しで指定して、型引数がメソッドの呼び出しの一部として指定されていない、ときに、型の推論はメソッド グループの各ジェネリック メソッドに適用されます。When a particular method group is specified in a method invocation, and no type arguments are specified as part of the method invocation, type inference is applied to each generic method in the method group. 型の推論に成功した場合、推論された型引数は、後続のオーバー ロードの解決用引数の種類を決定に使用されます。If type inference succeeds, then the inferred type arguments are used to determine the types of arguments for subsequent overload resolution. オーバー ロードの解決選択した場合、ジェネリック メソッドを呼び出すと、推論された型引数は、特定の呼び出しの実際の型引数として使用されます。If overload resolution chooses a generic method as the one to invoke, then the inferred type arguments are used as the actual type arguments for the invocation. 特定のメソッドの型の推定が失敗した場合、そのメソッドはオーバー ロードの解決には参加しません。If type inference for a particular method fails, that method does not participate in overload resolution. 型の推定、自体の障害では、バインド時のエラーは発生しません。The failure of type inference, in and of itself, does not cause a binding-time error. ただし、多くの場合、リード、バインド時のエラーを適切なメソッドを検索するオーバー ロードの解決が、失敗したときにします。However, it often leads to a binding-time error when overload resolution then fails to find any applicable methods.

指定された引数の数が、メソッドのパラメーターの数よりも異なる場合、推論すぐに失敗します。If the supplied number of arguments is different than the number of parameters in the method, then inference immediately fails. それ以外の場合、ジェネリック メソッドは、次のシグネチャであると仮定します。Otherwise, assume that the generic method has the following signature:

Tr M<X1,...,Xn>(T1 x1, ..., Tm xm)

フォームのメソッドの呼び出しでM(E1...Em)型の推定のタスクは、一意の型引数を検索するS1...Sn型パラメーターの各X1...Xnように呼び出しM<S1...Sn>(E1...Em)が有効になります。With a method call of the form M(E1...Em) the task of type inference is to find unique type arguments S1...Sn for each of the type parameters X1...Xn so that the call M<S1...Sn>(E1...Em) becomes valid.

推論の処理中に、各型パラメーターXi固定特定の種類にSiまたはfixed でない関連付けられている一連の境界.During the process of inference each type parameter Xi is either fixed to a particular type Si or unfixed with an associated set of bounds. 何らかの種類は、各範囲Tします。Each of the bounds is some type T. 最初に、各型変数Xi境界の空のセットを固定することはありません。Initially each type variable Xi is unfixed with an empty set of bounds.

型の推定は、フェーズで行われます。Type inference takes place in phases. 各フェーズは前のフェーズの結果に基づいて複数の型の変数の型引数を推測しようとします。Each phase will try to infer type arguments for more type variables based on the findings of the previous phase. 最初のフェーズでは、2 番目のフェーズは、型の変数を特定の種類を修正し、境界をさらに推論は、境界の初期推論。The first phase makes some initial inferences of bounds, whereas the second phase fixes type variables to specific types and infers further bounds. 2 番目のフェーズがありますが何度も繰り返されます。The second phase may have to be repeated a number of times.

注: 型の推論は行われますがジェネリック メソッドが呼び出されたときにだけでなく。Note: Type inference takes place not only when a generic method is called. メソッド グループの変換の型の推定については、「メソッド グループの変換の推論を入力に記載されて、一連の式の最適な一般的な種類を検索および一連の最適一般的な種類を検索します。式のします。Type inference for conversion of method groups is described in Type inference for conversion of method groups and finding the best common type of a set of expressions is described in Finding the best common type of a set of expressions.

最初のフェーズThe first phase

各メソッドの引数のEi:For each of the method arguments Ei:

  • 場合Ei、匿名関数、明示的なパラメーター型の推論(明示的なパラメーター型の推論) から行われるEiTiIf Ei is an anonymous function, an explicit parameter type inference (Explicit parameter type inferences) is made from Ei to Ti
  • の場合Ei型を持つUxi値を持つパラメーターには、下限の推論されるから U Ti.Otherwise, if Ei has a type U and xi is a value parameter then a lower-bound inference is made from U to Ti.
  • の場合Ei型を持つUxiは、refまたはoutパラメーター、の推定が正確なされるから UTiします。Otherwise, if Ei has a type U and xi is a ref or out parameter then an exact inference is made from U to Ti.
  • それ以外の場合、この引数の推論は行われません。Otherwise, no inference is made for this argument.

2 番目のフェーズThe second phase

2 番目のフェーズは、次のように処理されます。The second phase proceeds as follows:

  • すべてfixed でない変数を入力Xiかどうか依存(依存)、Xjは固定 (修正).All unfixed type variables Xi which do not depend on (Dependence) any Xj are fixed (Fixing).
  • このような型の変数が存在しない場合、すべてfixed でない入力変数Xi固定は次のすべてを保持します。If no such type variables exist, all unfixed type variables Xi are fixed for which all of the following hold:
    • 少なくとも 1 つの型の変数があるXjに依存します。 XiThere is at least one type variable Xj that depends on Xi
    • Xi 以外の空のセットを持つ境界Xi has a non-empty set of bounds
  • このような型の変数が存在しない場合にまだありますfixed でない変数の型、型推論は失敗します。If no such type variables exist and there are still unfixed type variables, type inference fails.
  • それ以外の場合、これ以上ない場合fixed でない型の変数の存在は、型の推定が成功するとします。Otherwise, if no further unfixed type variables exist, type inference succeeds.
  • それ以外のすべての引数のEi対応するパラメーターの型とTi場所、種類の出力(出力タイプ) が含まれてfixed でない変数を入力Xjが、入力の種類(入力の種類) はない、出力の型推論(出力型の推論) が行われたから Ei Tiします。Otherwise, for all arguments Ei with corresponding parameter type Ti where the output types (Output types) contain unfixed type variables Xj but the input types (Input types) do not, an output type inference (Output type inferences) is made from Ei to Ti. 2 番目のフェーズが繰り返されます。Then the second phase is repeated.

入力の種類Input types

場合Eメソッド グループ、または匿名関数を暗黙的に型指定とTがデリゲート型または式ツリー型のパラメーターの型をすべてT入力型E Tします。If E is a method group or implicitly typed anonymous function and T is a delegate type or expression tree type then all the parameter types of T are input types of E with type T.

出力の種類Output types

場合Eはメソッド グループ、または匿名関数とTがデリゲート型または式ツリー型の戻り値の型Tは、出力の種類の E T.If E is a method group or an anonymous function and T is a delegate type or expression tree type then the return type of T is an output type of E with type T.

依存関係Dependence

Fixed でない型の変数Xiに直接依存、fixed でない型の変数Xjいくつかの引数の場合EkTk Xj発生する、入力型Ek型でTkXiで発生する、出力の種類EkTkAn unfixed type variable Xi depends directly on an unfixed type variable Xj if for some argument Ek with type Tk Xj occurs in an input type of Ek with type Tk and Xi occurs in an output type of Ek with type Tk.

Xj 依存Xi場合Xjに直接依存Xi場合Xiに直接依存XkXk異なりますXjします。Xj depends on Xi if Xj depends directly on Xi or if Xi depends directly on Xk and Xk depends on Xj. したがって、「依存」に直接「依存」の推移的、再帰しないクロージャ。Thus "depends on" is the transitive but not reflexive closure of "depends directly on".

出力型の推論Output type inferences

出力の型推論されるからET次のように。An output type inference is made from an expression E to a type T in the following way:

  • 場合E推論された戻り値の型を持つ匿名関数は、 U (推定型を返す) とTがデリゲート型または戻り値の型の式ツリー型Tb下限の推論(下限の推論) が行われたから U Tbします。If E is an anonymous function with inferred return type U (Inferred return type) and T is a delegate type or expression tree type with return type Tb, then a lower-bound inference (Lower-bound inferences) is made from U to Tb.
  • の場合Eメソッド グループとTがデリゲート型またはパラメーターの型の式ツリー型T1...Tk型を返すとTb、オーバー ロードの解決とET1...Tkが得られます、1 つの戻り値の型を持つメソッドU下限の推論されるから U Tbします。Otherwise, if E is a method group and T is a delegate type or expression tree type with parameter types T1...Tk and return type Tb, and overload resolution of E with the types T1...Tk yields a single method with return type U, then a lower-bound inference is made from U to Tb.
  • の場合E型の式は、 U、、下限の推論されるから U T.Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.
  • それ以外の場合、推論は行われません。Otherwise, no inferences are made.

明示的なパラメーター型の推論Explicit parameter type inferences

明示的なパラメーター型の推論されるからET次のように。An explicit parameter type inference is made from an expression E to a type T in the following way:

  • 場合Eパラメーターの型を明示的に型指定された匿名関数U1...UkTがデリゲート型またはパラメーターの型の式ツリー型V1...Vk各しUi正確な推論(推測の正確な) が行われたから Ui 、対応するViします。If E is an explicitly typed anonymous function with parameter types U1...Uk and T is a delegate type or expression tree type with parameter types V1...Vk then for each Ui an exact inference (Exact inferences) is made from Ui to the corresponding Vi.

正確な推論Exact inferences

の推定が正確な**からUV次のようになります。An exact inference from a type U to a type V is made as follows:

  • 場合Vの 1 つ、 fixed でないXiUの正確な境界のセットに追加されますXiします。If V is one of the unfixed Xi then U is added to the set of exact bounds for Xi.

  • それ以外の場合、設定V1...VkU1...Ukは、次の場合のいずれかが当てはまる場合にチェックによって決まります。Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

    • V 配列型は、V1[...]U配列型は、U1[...]同じランクのV is an array type V1[...] and U is an array type U1[...] of the same rank
    • V 種類は、V1?U型です U1?V is the type V1? and U is the type U1?
    • V 構築された型は、C<V1...Vk>Uは構築された型です。 C<U1...Uk>V is a constructed type C<V1...Vk>and U is a constructed type C<U1...Uk>

    このような場合のいずれかが当てはまる場合、の推定が正確なされるからUi、対応するViします。If any of these cases apply then an exact inference is made from each Ui to the corresponding Vi.

  • それ以外の場合の推論は行われません。Otherwise no inferences are made.

下限の推論Lower-bound inferences

A下限の推論**からUV次のようになります。A lower-bound inference from a type U to a type V is made as follows:

  • 場合Vの 1 つ、 fixed でないXiUの下限のセットに追加されますXiします。If V is one of the unfixed Xi then U is added to the set of lower bounds for Xi.

  • の場合V型は、V1?U型は、U1?から下限の境界の推論が行われるU1V1します。Otherwise, if V is the type V1?and U is the type U1? then a lower bound inference is made from U1 to V1.

  • それ以外の場合、設定U1...UkV1...Vkは、次の場合のいずれかが当てはまる場合にチェックによって決まります。Otherwise, sets U1...Uk and V1...Vk are determined by checking if any of the following cases apply:

    • V 配列型は、V1[...]U配列型は、 U1[...] (または有効な基本型が型パラメーター U1[...]) に同じランクV is an array type V1[...] and U is an array type U1[...] (or a type parameter whose effective base type is U1[...]) of the same rank

    • V 1 つIEnumerable<V1>ICollection<V1>またはIList<V1>U1 次元配列の型は、 U1[](または有効な基本型が型パラメーター U1[])V is one of IEnumerable<V1>, ICollection<V1> or IList<V1> and U is a one-dimensional array type U1[](or a type parameter whose effective base type is U1[])

    • V 構築されたクラス、構造体、インターフェイスまたはデリゲートの型は、C<V1...Vk>一意の型があるとC<U1...Uk>ようにU(または、Uが型パラメーター、その効果的な基底クラスまたはその有効なインターフェイス セットのすべてのメンバー) は、同じで (直接または間接的に) を継承または実装 (直接または間接的に)C<U1...Uk>します。V is a constructed class, struct, interface or delegate type C<V1...Vk> and there is a unique type C<U1...Uk> such that U (or, if U is a type parameter, its effective base class or any member of its effective interface set) is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) C<U1...Uk>.

      (「一意性」制限が大文字と小文字のインターフェイスのことを意味C<T> {} class U: C<X>, C<Y> {}、推論がから推論するときに行われることはないUC<T>ためU1可能性がありますXまたはY)。(The "uniqueness" restriction means that in the case interface C<T> {} class U: C<X>, C<Y> {}, then no inference is made when inferring from U to C<T> because U1 could be X or Y.)

    このような場合のいずれかが当てはまる推論が行われる場合からUi、対応するVi次のように。If any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

    • 場合Uiは認識されない参照型であるため、の推定が正確なされますIf Ui is not known to be a reference type then an exact inference is made
    • の場合Uが配列型、下限の推論されますOtherwise, if U is an array type then a lower-bound inference is made
    • の場合VC<V1...Vk>推論が、i 番目の型パラメーターに依存し、 C:Otherwise, if V is C<V1...Vk> then inference depends on the i-th type parameter of C:
      • 共変である場合、下限の推論されます。If it is covariant then a lower-bound inference is made.
      • 反変である場合、上限推論されます。If it is contravariant then an upper-bound inference is made.
      • バリアント型でない場合、の推定が正確なされます。If it is invariant then an exact inference is made.
  • それ以外の場合、推論は行われません。Otherwise, no inferences are made.

上限の推論Upper-bound inferences

上限の推論**からUV次のようになります。An upper-bound inference from a type U to a type V is made as follows:

  • 場合Vの 1 つ、 fixed でないXiUの上限のセットに追加されますXiします。If V is one of the unfixed Xi then U is added to the set of upper bounds for Xi.

  • それ以外の場合、設定V1...VkU1...Ukは、次の場合のいずれかが当てはまる場合にチェックによって決まります。Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

    • U 配列型は、U1[...]V配列型は、V1[...]同じランクのU is an array type U1[...] and V is an array type V1[...] of the same rank

    • U 1 つIEnumerable<Ue>ICollection<Ue>またはIList<Ue>Vは 1 次元配列の型です。 Ve[]U is one of IEnumerable<Ue>, ICollection<Ue> or IList<Ue> and V is a one-dimensional array type Ve[]

    • U 種類は、U1?V型です V1?U is the type U1? and V is the type V1?

    • U 構築されたクラス、構造体、インターフェイスまたはデリゲートの型は、C<U1...Uk>V(直接または間接的に)、クラス、構造体、インターフェイスまたはデリゲートの型と一致する、(直接または間接的に) を継承または実装は、一意の型 C<V1...Vk>U is constructed class, struct, interface or delegate type C<U1...Uk> and V is a class, struct, interface or delegate type which is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) a unique type C<V1...Vk>

      (「一意性」制限ことを意味がある場合interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{}、推論がから推論するときに行われることはないC<U1>V<Q>します。(The "uniqueness" restriction means that if we have interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{}, then no inference is made when inferring from C<U1> to V<Q>. 推論が行われていないU1いずれかにX<Q>またはY<Q>)。Inferences are not made from U1 to either X<Q> or Y<Q>.)

    このような場合のいずれかが当てはまる推論が行われる場合からUi、対応するVi次のように。If any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

    • 場合Uiは認識されない参照型であるため、の推定が正確なされますIf Ui is not known to be a reference type then an exact inference is made
    • の場合Vが配列型、上限推論されますOtherwise, if V is an array type then an upper-bound inference is made
    • の場合UC<U1...Uk>推論が、i 番目の型パラメーターに依存し、 C:Otherwise, if U is C<U1...Uk> then inference depends on the i-th type parameter of C:
      • 共変である場合、上限推論されます。If it is covariant then an upper-bound inference is made.
      • 反変である場合、下限の推論されます。If it is contravariant then a lower-bound inference is made.
      • バリアント型でない場合、の推定が正確なされます。If it is invariant then an exact inference is made.
  • それ以外の場合、推論は行われません。Otherwise, no inferences are made.

修正Fixing

Fixed でない型の変数Xi境界のセットでは固定次のようにします。An unfixed type variable Xi with a set of bounds is fixed as follows:

  • 一連の候補型Ujの境界のセット内のすべての型のセットとしては、まずXiします。The set of candidate types Uj starts out as the set of all types in the set of bounds for Xi.
  • 各バインドを考察しXi順番。各正確なバインドのUXiすべての種類Ujと同じされないU候補セットから削除されます。We then examine each bound for Xi in turn: For each exact bound U of Xi all types Uj which are not identical to U are removed from the candidate set. 各下限の境界のUXiすべての種類Ujがあるがいないからの暗黙的な変換U候補セットから削除されます。For each lower bound U of Xi all types Uj to which there is not an implicit conversion from U are removed from the candidate set. 各上限のUXiすべての種類Ujからどのいないへの暗黙的な変換U候補セットから削除されます。For each upper bound U of Xi all types Uj from which there is not an implicit conversion to U are removed from the candidate set.
  • 残りの候補の種類の間での ifUj一意の型があるVが暗黙的な変換をすべて、その他の候補の種類にしからXiに固定されてVIf among the remaining candidate types Uj there is a unique type V from which there is an implicit conversion to all the other candidate types, then Xi is fixed to V.
  • それ以外の場合、型の推論は失敗します。Otherwise, type inference fails.

推論された戻り値の型Inferred return type

推論される匿名関数の型を返すF型推論とオーバー ロードの解決中に使用されます。The inferred return type of an anonymous function F is used during type inference and overload resolution. すべてのパラメーター型がわかっていますが、いずれかが明示的に指定するための匿名関数の変換によって提供される、または推論型の推定をそれを囲むジェネリック中に、匿名関数に対する推論された戻り値の型を決定のみメソッドの呼び出し。The inferred return type can only be determined for an anonymous function where all parameter types are known, either because they are explicitly given, provided through an anonymous function conversion or inferred during type inference on an enclosing generic method invocation.

結果型を推論は次のように決定されます。The inferred result type is determined as follows:

  • 場合、本文のFは、型の場合の推定の結果の型を持つFその式の種類です。If the body of F is an expression that has a type, then the inferred result type of F is the type of that expression.
  • 場合、本文のFは、ブロックとブロックの内の式のセットreturnステートメントが最適な一般的な型T(式のセットの最適な一般的な種類を検索する) の推定の結果の型、FTします。If the body of F is a block and the set of expressions in the block's return statements has a best common type T (Finding the best common type of a set of expressions), then the inferred result type of F is T.
  • 場合は、結果型を推論できませんFします。Otherwise, a result type cannot be inferred for F.

戻り値の型を推論は次のように決定されます。The inferred return type is determined as follows:

  • 場合Fasync およびの本文はFnothing として分類される式は、(式の分類)、または return ステートメントに式が、されていないステートメント ブロック、推論された戻り値の型が System.Threading.Tasks.TaskIf F is async and the body of F is either an expression classified as nothing (Expression classifications), or a statement block where no return statements have expressions, the inferred return type is System.Threading.Tasks.Task
  • 場合F非同期であり、推論された結果型を持つT、推論される戻り値の型がSystem.Threading.Tasks.Task<T>します。If F is async and has an inferred result type T, the inferred return type is System.Threading.Tasks.Task<T>.
  • 場合Fでは、非同期であり、推論された結果型を持つT、推論される戻り値の型がTします。If F is non-async and has an inferred result type T, the inferred return type is T.
  • それ以外の場合の戻り値の型を推論できませんFします。Otherwise a return type cannot be inferred for F.

匿名関数に関連する型の推定の例に、Selectで宣言されている拡張メソッド、System.Linq.Enumerableクラス。As an example of type inference involving anonymous functions, consider the Select extension method declared in the System.Linq.Enumerable class:

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句では、クラスとCustomerで、Name型のプロパティstringSelectメソッドを使用して、顧客の一覧の名前を選択します。Assuming the System.Linq namespace was imported with a using clause, and given a class Customer with a Name property of type string, the Select method can be used to select the names of a list of customers:

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

拡張メソッドの呼び出し (拡張メソッド呼び出し) のSelect静的メソッドの呼び出しに呼び出しを書き直すことによって処理されます。The extension method invocation (Extension method invocations) of Select is processed by rewriting the invocation to a static method invocation:

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

型引数が明示的に指定されていないために、型の推定は、型引数の推論に使用されます。Since type arguments were not explicitly specified, type inference is used to infer the type arguments. 最初に、customers引数に関連する、sourceパラメーターへの推論TするCustomerします。First, the customers argument is related to the source parameter, inferring T to be Customer. 推論プロセスが、上記で説明したが、匿名関数を使用して入力c型が指定Customerと式c.Nameの戻り値の型に関連する、selectorパラメーターへの推論Sにするstring.Then, using the anonymous function type inference process described above, c is given type Customer, and the expression c.Name is related to the return type of the selector parameter, inferring S to be string. したがって、呼び出しと同じです。Thus, the invocation is equivalent to

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

され、結果は型のIEnumerable<string>します。and the result is of type IEnumerable<string>.

次の例では、匿名関数の型の推定により、ジェネリック メソッドの呼び出しで引数の間を"flow"に型情報。The following example demonstrates how anonymous function type inference allows type information to "flow" between arguments in a generic method invocation. メソッドを指定します。Given the method:

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

呼び出しの推論を入力します。Type inference for the invocation:

double seconds = F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds);

次のように処理されます。最初に、引数"1:15:30"に関連する、valueパラメーターへの推論Xするstringします。proceeds as follows: First, the argument "1:15:30" is related to the value parameter, inferring X to be string. Then の場合は、最初の匿名関数のパラメーター s、推論された型が指定stringと式TimeSpan.Parse(s)の戻り値の型に関連するf1推論するとき、YするSystem.TimeSpanします。Then, the parameter of the first anonymous function, s, is given the inferred type string, and the expression TimeSpan.Parse(s) is related to the return type of f1, inferring Y to be System.TimeSpan. 2 番目の匿名関数のパラメーターでは最後に、 t、推論された型が指定System.TimeSpan、および式t.TotalSecondsの戻り値の型に関連するf2推論するとき、ZするdoubleFinally, the parameter of the second anonymous function, t, is given the inferred type System.TimeSpan, and the expression t.TotalSeconds is related to the return type of f2, inferring Z to be double. したがって、呼び出しの結果は型doubleします。Thus, the result of the invocation is of type double.

メソッド グループの変換の型の推論Type inference for conversion of method groups

ジェネリック メソッドの呼び出しと同様に、型の推論する必要がありますも時に適用される、メソッド グループMを特定のデリゲート型に変換がジェネリック メソッドを含むD(メソッド グループ変換)。Similar to calls of generic methods, type inference must also be applied when a method group M containing a generic method is converted to a given delegate type D (Method group conversions). メソッドの指定Given a method

Tr M<X1...Xn>(T1 x1 ... Tm xm)

メソッド グループMデリゲート型に割り当てられているD型の推定のタスクは、型引数を検索するS1...Snように式。and the method group M being assigned to the delegate type D the task of type inference is to find type arguments S1...Sn so that the expression:

M<S1...Sn>

互換性のあるになります (デリゲートの宣言) とDします。becomes compatible (Delegate declarations) with D.

ジェネリック メソッドの呼び出しの型推論アルゴリズムとは異なりこの場合がある引数だけ、引数なしします。Unlike the type inference algorithm for generic method calls, in this case there are only argument types, no argument expressions. 具体的には、匿名関数がないため、推論の複数のフェーズの必要はありません。In particular, there are no anonymous functions and hence no need for multiple phases of inference.

代わりに、すべてXiと見なされますfixed でない、および下限の推論されるから各引数の型UjD対応するパラメーター型TjMします。Instead, all Xi are considered unfixed, and a lower-bound inference is made from each argument type Uj of D to the corresponding parameter type Tj of M. いずれかの場合、Xi境界が見つからなかったため、型推論が失敗します。If for any of the Xi no bounds were found, type inference fails. それ以外の場合、すべてXi固定を対応するSi型の推定の結果であります。Otherwise, all Xi are fixed to corresponding Si, which are the result of type inference.

一連の式の最適な一般的な種類を検索します。Finding the best common type of a set of expressions

場合によっては、共通の型を式のセットを推論する必要があります。In some cases, a common type needs to be inferred for a set of expressions. 特定の暗黙的に型指定された配列の要素の型と匿名関数の戻り値の型でブロック本文にこの方法であります。In particular, the element types of implicitly typed arrays and the return types of anonymous functions with block bodies are found in this way.

直感的に、与えられた一連の式のE1...Emこの推定は、メソッドの呼び出しに相当する必要がありますIntuitively, given a set of expressions E1...Em this inference should be equivalent to calling a method

Tr M<X>(X x1 ... X xm)

Ei引数として。with the Ei as arguments.

正確には、推論から始まって、 fixed でない型の変数Xします。More precisely, the inference starts out with an unfixed type variable X. 出力型の推論、割り当てられているからEiXします。Output type inferences are then made from each Ei to X. 最後に、X固定し、成功した場合、その結果、入力Sは、式の結果として得られる最適な一般的な型です。Finally, X is fixed and, if successful, the resulting type S is the resulting best common type for the expressions. そのような場合S存在する場合、式は、最高の一般的な型であるありません。If no such S exists, the expressions have no best common type.

オーバー ロードの解決Overload resolution

オーバー ロードの解決は、指定された引数リストおよび候補関数メンバーのセットを起動する最適な関数メンバーを選択するためのバインド時メカニズムです。Overload resolution is a binding-time mechanism for selecting the best function member to invoke given an argument list and a set of candidate function members. オーバー ロードの解決は、c# の次の異なるコンテキストで呼び出す関数メンバーを選択します。Overload resolution selects the function member to invoke in the following distinct contexts within C#:

前のセクションで詳しく説明されているように固有の方法で候補関数メンバーのセットと引数のリストを定義これらのコンテキストの各とします。Each of these contexts defines the set of candidate function members and the list of arguments in its own unique way, as described in detail in the sections listed above. メソッドの呼び出しの候補のセットでマークされているメソッドが含まれませんなどoverride(メンバー ルックアップ) との基本クラスのメソッドの候補場合は派生クラスで任意のメソッドは、適用可能な (メソッドの呼び出し)。For example, the set of candidates for a method invocation does not include methods marked override (Member lookup), and methods in a base class are not candidates if any method in a derived class is applicable (Method invocations).

関数メンバーの候補と引数リストを特定すると、最適な関数メンバーの選択は常に同じです。Once the candidate function members and the argument list have been identified, the selection of the best function member is the same in all cases:

  • 該当する候補の関数メンバーのセットを指定するには、最善の関数メンバーであるセットが配置されています。Given the set of applicable candidate function members, the best function member in that set is located. セットの 1 つだけの関数メンバーの場合は、その関数のメンバーは最適な関数メンバーです。If the set contains only one function member, then that function member is the best function member. 最適な関数メンバーは 1 つの関数メンバーを関数の各メンバーは、の規則を使用して他のすべての関数メンバーと比較されるときに、指定した引数リストに対して他のすべての関数メンバーよりも優れていますが、それ以外の場合、 最適な関数メンバーします。Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in Better function member. 他のすべての関数メンバーより 1 つの関数メンバーが一致しない場合は、関数メンバーの呼び出しがあいまいですし、およびバインド エラーが発生します。If there is not exactly one function member that is better than all other function members, then the function member invocation is ambiguous and a binding-time error occurs.

次のセクションでは、用語の正確な意味を定義する適用可能な関数メンバー最適な関数メンバーします。The following sections define the exact meanings of the terms applicable function member and better function member.

適用可能な関数メンバーApplicable function member

関数メンバーはモード、適用可能な関数メンバー引数リストに対してAが true で、次のすべての場合。A function member is said to be an applicable function member with respect to an argument list A when all of the following are true:

  • 各引数A関数メンバーの宣言でのパラメーターに対応しています」の説明に従って対応するパラメーター引数に対応するない任意のパラメーターは省略可能なパラメーター。Each argument in A corresponds to a parameter in the function member declaration as described in Corresponding parameters, and any parameter to which no argument corresponds is an optional parameter.
  • 各引数にA、渡す引数のパラメーター (つまり、値は、 ref、またはout) は、対応するパラメーターのパラメーター渡しモードと同じですし、For each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is identical to the parameter passing mode of the corresponding parameter, and
    • 値を持つパラメーターまたはパラメーターの配列では、暗黙的な変換 (暗黙的な変換) 引数から、対応するパラメーターの型に存在するかfor a value parameter or a parameter array, an implicit conversion (Implicit conversions) exists from the argument to the type of the corresponding parameter, or
    • refまたはoutパラメーターの引数の型は、対応するパラメーターの型と同じです。for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. 結局、refまたはoutパラメーターが渡される引数の別名です。After all, a ref or out parameter is an alias for the argument passed.

パラメーター配列を含む関数メンバーの関数メンバーは、上記の規則が適切である場合に適用されると言われますその正規形します。For a function member that includes a parameter array, if the function member is applicable by the above rules, it is said to be applicable in its normal form. パラメーター配列を含む関数のメンバーが、標準形式で適用されない場合は、関数メンバーがで該当する代わりに可能性、フォーム展開:If a function member that includes a parameter array is not applicable in its normal form, the function member may instead be applicable in its expanded form:

  • 関数メンバーの宣言でパラメーターの配列を 0 に置き換えることにより拡張されたフォームを構築またはパラメーターの要素型の複数値パラメーターの配列など、引数リストの引数の数A合計と一致します。パラメーターの数。The expanded form is constructed by replacing the parameter array in the function member declaration with zero or more value parameters of the element type of the parameter array such that the number of arguments in the argument list A matches the total number of parameters. 場合A関数メンバーの宣言で固定のパラメーター数よりも少ない引数を持つ場合、関数メンバーの拡張の形式は構築できませんのでは適用されません。If A has fewer arguments than the number of fixed parameters in the function member declaration, the expanded form of the function member cannot be constructed and is thus not applicable.
  • それ以外の場合、拡張の形式は、の各引数の場合適用A引数のパラメーター渡しモードは、対応するパラメーターのパラメーター渡しモードと同じですし、Otherwise, the expanded form is applicable if for each argument in A the parameter passing mode of the argument is identical to the parameter passing mode of the corresponding parameter, and
    • 固定値を持つパラメーターまたは拡張、暗黙的な変換によって作成された値を持つパラメーター (暗黙的な変換) 引数の型から、対応するパラメーターの型に存在するか、for a fixed value parameter or a value parameter created by the expansion, an implicit conversion (Implicit conversions) exists from the type of the argument to the type of the corresponding parameter, or
    • refまたはoutパラメーターの引数の型は、対応するパラメーターの型と同じです。for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter.

最適な関数メンバーBetter function member

最適な関数メンバーを決定するためには、式を含むだけ、引数自体、元の引数リストに表示される順序で取り除いた引数リスト A が構築されます。For the purposes of determining the better function member, a stripped-down argument list A is constructed containing just the argument expressions themselves in the order they appear in the original argument list.

パラメーターは、各メンバーは、次のように構築されている候補関数の一覧です。Parameter lists for each of the candidate function members are constructed in the following way:

  • 関数メンバーが展開された形式でのみ使用できる場合は、拡張の形式が使用されます。The expanded form is used if the function member was applicable only in the expanded form.
  • 対応する引数なしで省略可能なパラメーターがパラメーター リストから削除されます。Optional parameters with no corresponding arguments are removed from the parameter list
  • パラメーターの順序は変更を対応する引数として、引数リスト内の同じ位置にあります。The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list.

引数リストを指定されたA一連の引数の式の{E1, E2, ..., En}と 2 つの適用可能な関数メンバーMpMqパラメーターの型で{P1, P2, ..., Pn}{Q1, Q2, ..., Qn}Mpとして定義されている、最適な関数メンバーよりMq場合Given an argument list A with a set of argument expressions {E1, E2, ..., En} and two applicable function members Mp and Mq with parameter types {P1, P2, ..., Pn} and {Q1, Q2, ..., Qn}, Mp is defined to be a better function member than Mq if

  • 各引数の暗黙の変換からExQxから暗黙の変換よりも適切でないExPxfor each argument, the implicit conversion from Ex to Qx is not better than the implicit conversion from Ex to Px, and
  • 少なくとも 1 つの引数からの変換のExPxからの変換よりもをお勧めExQxします。for at least one argument, the conversion from Ex to Px is better than the conversion from Ex to Qx.

場合、この評価を実行するときにMpまたはMqが展開されたフォームでは、該当するPxまたはQxパラメーター リストの拡張の形式でパラメーターを参照します。When performing this evaluation, if Mp or Mq is applicable in its expanded form, then Px or Qx refers to a parameter in the expanded form of the parameter list.

場合は、パラメーター型シーケンス {P1, P2, ..., Pn}{Q1, Q2, ..., Qn}は同等です (つまり各Piが、対応する id 変換Qi)、良いを判断する順序で、次のリンク付け規則が適用されます関数のメンバー。In case the parameter type sequences {P1, P2, ..., Pn} and {Q1, Q2, ..., Qn} are equivalent (i.e. each Pi has an identity conversion to the corresponding Qi), the following tie-breaking rules are applied, in order, to determine the better function member.

  • 場合Mpは非ジェネリック メソッドとMqはジェネリック メソッドでは、MpよりはMqIf Mp is a non-generic method and Mq is a generic method, then Mp is better than Mq.
  • の場合Mpオプションは、標準形式に該当し、Mqが、params配列し、は、拡張形式でのみ使用できるMpよりも優れていますがMqOtherwise, if Mp is applicable in its normal form and Mq has a params array and is applicable only in its expanded form, then Mp is better than Mq.
  • の場合Mpよりもパラメーターを宣言の詳細がMq、しMpよりはMqします。Otherwise, if Mp has more declared parameters than Mq, then Mp is better than Mq. これは、両方の方法がある場合に発生することがparams配列と、拡張形式でのみ適用されます。This can occur if both methods have params arrays and are applicable only in their expanded forms.
  • それ以外の場合のすべてのパラメーターMpで少なくとも 1 つの省略可能なパラメーターの代わりに使用する既定の引数が必要がありますが、対応する引数を持つMqMpよりはMqします。Otherwise if all parameters of Mp have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in Mq then Mp is better than Mq.
  • の場合Mpよりも具体的なパラメーターの型を持つMq、しMpよりはMqします。Otherwise, if Mp has more specific parameter types than Mq, then Mp is better than Mq. ように{R1, R2, ..., Rn}{S1, S2, ..., Sn}のインスタンス化されていないと、展開されていないパラメーターの型を表すMpMqします。Let {R1, R2, ..., Rn} and {S1, S2, ..., Sn} represent the uninstantiated and unexpanded parameter types of Mp and Mq. Mpパラメーターの型がよりも具体的Mqの場合、各パラメーターのRxよりも小さい固有ではないSxと少なくとも 1 つのパラメーターのRxよりも特定Sx:Mp's parameter types are more specific than Mq's if, for each parameter, Rx is not less specific than Sx, and, for at least one parameter, Rx is more specific than Sx:
    • 型パラメーターは、非型パラメーターよりも小さい固有です。A type parameter is less specific than a non-type parameter.
    • 再帰的に構築された型が別の構築された型 (型引数の同じ番号) を持つ場合、少なくとも 1 つの入力引数の指定がより具体的と型引数が、それ以外の対応する型の引数よりも限定しないよりも限定します。Recursively, a constructed type is more specific than another constructed type (with the same number of type arguments) if at least one type argument is more specific and no type argument is less specific than the corresponding type argument in the other.
    • 配列型は、最初の要素の型は、2 番目の要素の型よりも具体的である場合 (同じ次元数) で別の配列型より固有です。An array type is more specific than another array type (with the same number of dimensions) if the element type of the first is more specific than the element type of the second.
  • それ以外の場合 1 つのメンバーは非リフトされた演算子と、リフトされた演算子、もう一方は、非リフトされた 1 つが向上します。Otherwise if one member is a non-lifted operator and the other is a lifted operator, the non-lifted one is better.
  • それ以外の場合、どちらの関数メンバーお勧めします。Otherwise, neither function member is better.

式からより適切な変換Better conversion from expression

暗黙的な変換を指定C1式から変換E型にT1、および暗黙的な変換をC2式から変換E型にT2C1変換の改善よりC2場合Eは完全に一致しないT2し、次の少なくとも 1 つを保持します。Given an implicit conversion C1 that converts from an expression E to a type T1, and an implicit conversion C2 that converts from an expression E to a type T2, C1 is a better conversion than C2 if E does not exactly match T2 and at least one of the following holds:

完全に一致する式Exactly matching Expression

式が指定Eと型TE完全に一致するT次のいずれかが保持している場合。Given an expression E and a type T, E exactly matches T if one of the following holds:

  • E 型を持つSからの id 変換が存在してSTE has a type S, and an identity conversion exists from S to T
  • E 匿名関数、Tデリゲート型は、Dまたは式ツリー型Expression<D>し、次のいずれかを保持します。E is an anonymous function, T is either a delegate type D or an expression tree type Expression<D> and one of the following holds:
    • 推論された戻り値の型Xが存在するEのパラメーター リストのコンテキストでD(推定型を返す) からの id 変換が存在してXの戻り値の型に DAn inferred return type X exists for E in the context of the parameter list of D (Inferred return type), and an identity conversion exists from X to the return type of D
    • いずれかEは非同期ではないとD戻り値の型を持つYまたはEは async とD戻り値の型を持つTask<Y>、し、次のいずれかを保持します。Either E is non-async and D has a return type Y or E is async and D has a return type Task<Y>, and one of the following holds:
      • 本文Eを完全に一致する式は、 YThe body of E is an expression that exactly matches Y
      • 本文Eを完全に一致するすべての return ステートメント返しますが、式、ステートメント ブロックには YThe body of E is a statement block where every return statement returns an expression that exactly matches Y

変換対象の向上Better conversion target

2 つの種類を指定T1T2T1よりも優れた、変換対象T2場合からの暗黙的な変換なしT2T1が存在して、次の少なくとも 1 つを保持します。Given two different types T1 and T2, T1 is a better conversion target than T2 if no implicit conversion from T2 to T1 exists, and at least one of the following holds:

  • 暗黙的な変換T1T2が存在します。An implicit conversion from T1 to T2 exists
  • T1 デリゲート型は、D1または式ツリー型Expression<D1>T2デリゲート型は、D2または式ツリー型Expression<D2>D1戻り値の型を持つS1のいずれかと、次の保留:T1 is either a delegate type D1 or an expression tree type Expression<D1>, T2 is either a delegate type D2 or an expression tree type Expression<D2>, D1 has a return type S1 and one of the following holds:
    • D2 void を返すD2 is void returning
    • D2 戻り値の型を持つS2、およびS1よりも優れた変換対象は、 S2D2 has a return type S2, and S1 is a better conversion target than S2
  • T1 Task<S1>T2Task<S2>、およびS1よりも優れた変換対象は、 S2T1 is Task<S1>, T2 is Task<S2>, and S1 is a better conversion target than S2
  • T1 S1またはS1?場所S1は符号付き整数型とT2S2またはS2?場所S2は符号なし整数型。T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. 具体的には、次のように使用します。Specifically:
    • S1 sbyteS2byteushortuint、または ulongS1 is sbyte and S2 is byte, ushort, uint, or ulong
    • S1 shortS2ushortuint、または ulongS1 is short and S2 is ushort, uint, or ulong
    • S1 intS2uint、または ulongS1 is int and S2 is uint, or ulong
    • S1 longS2ulongS1 is long and S2 is ulong

ジェネリック クラスのオーバー ロードOverloading in generic classes

宣言された署名は、一意である必要があります、シグネチャが同じ結果を型引数の置換することができます。While signatures as declared must be unique, it is possible that substitution of type arguments results in identical signatures. このような場合は、上記のオーバー ロードの解決の対フスェケェルェニェヒ規則は、特定のメンバーが選択されます。In such cases, the tie-breaking rules of overload resolution above will pick the most specific member.

次の例では、有効であり、このルールに従って無効であるオーバー ロードを示します。The following examples show overloads that are valid and invalid according to this rule:

interface I1<T> {...}

interface I2<T> {...}

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

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

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

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

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

    void F6(ref U u);             // valid overload
    void F6(out V v);
}

コンパイル時の動的なオーバー ロードの解決の確認Compile-time checking of dynamic overload resolution

最も動的にバインドされた操作の解決候補のセットはコンパイル時に既知ではありません。For most dynamically bound operations the set of possible candidates for resolution is unknown at compile-time. ただし、場合によっては候補の集合がコンパイル時に呼ばれるは。In certain cases, however the candidate set is known at compile-time:

  • 動的引数を持つ静的メソッドの呼び出しStatic method calls with dynamic arguments
  • 受信側が動的な式ではないインスタンス メソッドの呼び出しInstance method calls where the receiver is not a dynamic expression
  • インデクサー呼び出しの受信側が動的な式ではありません。Indexer calls where the receiver is not a dynamic expression
  • 動的引数を持つコンス トラクターの呼び出しConstructor calls with dynamic arguments

このような場合は、制限付きのコンパイル時チェックが実行時にいずれかが適用可能性があるかどうかに表示するには、各候補に対して実行されます。このチェックは、次の手順で構成されます。In these cases a limited compile-time check is performed for each candidate to see if any of them could possibly apply at run-time.This check consists of the following steps:

  • 部分型の推定:任意の型引数を型の引数に直接または間接的には依存しませんdynamic推論のルールを使用して型推論します。Partial type inference: Any type argument that does not depend directly or indirectly on an argument of type dynamic is inferred using the rules of Type inference. 残りの型引数は既知ではありません。The remaining type arguments are unknown.
  • 部分的な適用性チェック:適用性のチェックによる適用可能な関数メンバー、既知の型がないパラメーターは無視されますが、します。Partial applicability check: Applicability is checked according to Applicable function member, but ignoring parameters whose types are unknown.
  • このテストに合格する候補がない、コンパイル時エラーが発生します。If no candidate passes this test, a compile-time error occurs.

関数メンバーの呼び出しFunction member invocation

このセクションでは、特定の関数メンバーを呼び出すための実行時に発生するプロセスについて説明します。This section describes the process that takes place at run-time to invoke a particular function member. バインディング時の処理の呼び出しは、場合によって適用することでオーバー ロードの解決、一連の関数メンバーの候補にするには、特定のメンバーが既に判断したと見なされます。It is assumed that a binding-time process has already determined the particular member to invoke, possibly by applying overload resolution to a set of candidate function members.

呼び出しプロセスを記述するために、関数メンバーは、2 つのカテゴリに分類されます。For purposes of describing the invocation process, function members are divided into two categories:

  • 静的な関数メンバー。Static function members. これらは、インスタンス コンス トラクター、静的メソッド、静的なプロパティ アクセサー、およびユーザー定義の演算子。These are instance constructors, static methods, static property accessors, and user-defined operators. 静的な関数メンバーは、非仮想では常にします。Static function members are always non-virtual.
  • 関数のインスタンス メンバーです。Instance function members. これらは、インスタンス メソッド、インスタンス プロパティ アクセサー、およびインデクサーのアクセサー。These are instance methods, instance property accessors, and indexer accessors. インスタンス関数メンバーは、仮想でないか、仮想、およびは、特定のインスタンスに常に呼び出されます。Instance function members are either non-virtual or virtual, and are always invoked on a particular instance. インスタンスがインスタンス式によって計算され、関数はメンバー内でアクセス可能になりますthis(このアクセス)。The instance is computed by an instance expression, and it becomes accessible within the function member as this (This access).

関数メンバーの呼び出しの実行時の処理は、次の手順で構成されていますここM関数メンバーは、し、場合は、Mインスタンス メンバーEインスタンス式です。The run-time processing of a function member invocation consists of the following steps, where M is the function member and, if M is an instance member, E is the instance expression:

  • 場合Mは静的な関数メンバーです。If M is a static function member:

    • 」の説明に従って、引数リストが評価される引数リストします。The argument list is evaluated as described in Argument lists.
    • M 呼び出されます。M is invoked.
  • 場合Mインスタンス関数のメンバーで宣言、 value_type:If M is an instance function member declared in a value_type:

    • E 評価されます。E is evaluated. この評価は、例外を発生させ場合、その後の手順は実行されません。If this evaluation causes an exception, then no further steps are executed.
    • 場合E変数、その後の一時ローカル変数として分類されないEの型が作成されると値のEその変数に代入されます。If E is not classified as a variable, then a temporary local variable of E's type is created and the value of E is assigned to that variable. E 一時ローカル変数への参照として再分類します。E is then reclassified as a reference to that temporary local variable. 一時変数のアクセシビリティがthisMが、その他の方法ではありません。The temporary variable is accessible as this within M, but not in any other way. したがって、場合にのみEが true の変数は、呼び出し元が、変更を確認できますをMthisします。Thus, only when E is a true variable is it possible for the caller to observe the changes that M makes to this.
    • 」の説明に従って、引数リストが評価される引数リストします。The argument list is evaluated as described in Argument lists.
    • M 呼び出されます。M is invoked. によって参照される変数Eによって参照される変数になりますthisします。The variable referenced by E becomes the variable referenced by this.
  • 場合Mインスタンス関数のメンバーで宣言、 reference_type:If M is an instance function member declared in a reference_type:

    • E 評価されます。E is evaluated. この評価は、例外を発生させ場合、その後の手順は実行されません。If this evaluation causes an exception, then no further steps are executed.
    • 」の説明に従って、引数リストが評価される引数リストします。The argument list is evaluated as described in Argument lists.
    • 場合の種類Eは、 value_type、ボックス化変換 (ボックス化変換) に変換する実行Eを入力するobjectEと見なされます型にするobjectで、次の手順。If the type of E is a value_type, a boxing conversion (Boxing conversions) is performed to convert E to type object, and E is considered to be of type object in the following steps. この場合、Mのメンバーである可能性がありますのみSystem.Objectします。In this case, M could only be a member of System.Object.
    • Eがチェックを有効にします。The value of E is checked to be valid. 場合の値EnullSystem.NullReferenceExceptionがスローされます、以降の手順は実行されません。If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
    • 呼び出す関数メンバーの実装が決定されます。The function member implementation to invoke is determined:
      • バインディング時の型の場合Eインターフェイスで呼び出す関数メンバーの実装は、Mによって参照されるインスタンスの実行時の型によって提供されるEします。If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. この関数のメンバーがインターフェイスのマッピング規則を適用して決定されます (インターフェイス マップ) の実装を決定するMによって参照されるインスタンスの実行時の型によって提供されるEします。This function member is determined by applying the interface mapping rules (Interface mapping) to determine the implementation of M provided by the run-time type of the instance referenced by E.
      • の場合M仮想関数のメンバーでは、呼び出す関数メンバーの実装は、Mによって参照されるインスタンスの実行時の型によって提供されるEします。Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. この関数のメンバーが、最派生実装を決定するルールを適用して決定されます (仮想メソッド) のMによって参照されるインスタンスの実行時の型に関してEします。This function member is determined by applying the rules for determining the most derived implementation (Virtual methods) of M with respect to the run-time type of the instance referenced by E.
      • それ以外の場合、M非仮想関数メンバー、および関数メンバーを呼び出すが、M自体。Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.
    • 上記の手順で決定関数メンバーの実装が呼び出されます。The function member implementation determined in the step above is invoked. によって参照されるオブジェクトEによって参照されるオブジェクトになりますthisします。The object referenced by E becomes the object referenced by this.

ボックス化されたインスタンス上の呼び出しInvocations on boxed instances

関数メンバーの実装で、 value_typeのボックス化されたインスタンスを呼び出すことができますvalue_type次の状況で。A function member implemented in a value_type can be invoked through a boxed instance of that value_type in the following situations:

  • 関数メンバーの場合、override型から継承されたメソッドのobjectが型のインスタンス式から呼び出されるとobjectします。When the function member is an override of a method inherited from type object and is invoked through an instance expression of type object.
  • 関数メンバーがインターフェイスの関数メンバーの実装がのインスタンス式から呼び出される、 interface_typeします。When the function member is an implementation of an interface function member and is invoked through an instance expression of an interface_type.
  • ときに関数メンバーはデリゲートを介して呼び出されます。When the function member is invoked through a delegate.

変数を含むこのような状況でボックス化されたインスタンスと見なされます、 value_type、この変数で参照される変数になりthis関数メンバーの呼び出し内で。In these situations, the boxed instance is considered to contain a variable of the value_type, and this variable becomes the variable referenced by this within the function member invocation. 具体的には、関数メンバーがボックス化されたインスタンスで呼び出されると、ボックス化されたインスタンスに含まれる値を変更する関数メンバーの可能なは、これは意味します。In particular, this means that when a function member is invoked on a boxed instance, it is possible for the function member to modify the value contained in the boxed instance.

基本式Primary expressions

一次式には、式の最も簡単なフォームが含まれます。Primary expressions include the simplest forms of expressions.

primary_expression
    : primary_no_array_creation_expression
    | array_creation_expression
    ;

primary_no_array_creation_expression
    : literal
    | interpolated_string_expression
    | simple_name
    | parenthesized_expression
    | member_access
    | invocation_expression
    | element_access
    | this_access
    | base_access
    | post_increment_expression
    | post_decrement_expression
    | object_creation_expression
    | delegate_creation_expression
    | anonymous_object_creation_expression
    | typeof_expression
    | checked_expression
    | unchecked_expression
    | default_value_expression
    | nameof_expression
    | anonymous_method_expression
    | primary_no_array_creation_expression_unsafe
    ;

一次式に分かれていますarray_creation_expressions とprimary_no_array_creation_expression秒。Primary expressions are divided between array_creation_expressions and primary_no_array_creation_expressions. この方法では、配列作成式を扱う、と共に、他の式の単純なフォームを指定することではなくによりなどの混乱を招く可能性のあるコードを許可しないようにする文法Treating array-creation-expression in this way, rather than listing it along with the other simple expression forms, enables the grammar to disallow potentially confusing code such as

object o = new int[3][1];

それ以外の場合として解釈されるします。which would otherwise be interpreted as

object o = (new int[3])[1];

リテラルLiterals

A primary_expressionで構成される、リテラル(リテラル) 値として分類されます。A primary_expression that consists of a literal (Literals) is classified as a value.

挿入文字列Interpolated strings

Interpolated_string_expressionから成る、$記号の後に正規表現または逐語的文字列リテラル、穴の区切られ{}式を囲みますおよび書式設定仕様。An interpolated_string_expression consists of a $ sign followed by a regular or verbatim string literal, wherein holes, delimited by { and }, enclose expressions and formatting specifications. 補間文字列式の結果とは、 interpolated_string_literalが分割されている個々 のトークンに」の説明に従ってリテラル文字列の補間します。An interpolated string expression is the result of an interpolated_string_literal that has been broken up into individual tokens, as described in Interpolated string literals.

interpolated_string_expression
    : '$' interpolated_regular_string
    | '$' interpolated_verbatim_string
    ;

interpolated_regular_string
    : interpolated_regular_string_whole
    | interpolated_regular_string_start interpolated_regular_string_body interpolated_regular_string_end
    ;

interpolated_regular_string_body
    : interpolation (interpolated_regular_string_mid interpolation)*
    ;

interpolation
    : expression
    | expression ',' constant_expression
    ;

interpolated_verbatim_string
    : interpolated_verbatim_string_whole
    | interpolated_verbatim_string_start interpolated_verbatim_string_body interpolated_verbatim_string_end
    ;

interpolated_verbatim_string_body
    : interpolation (interpolated_verbatim_string_mid interpolation)+
    ;

Constant_expression 、補間で暗黙的に変換をいる必要がありますintします。The constant_expression in an interpolation must have an implicit conversion to int.

Interpolated_string_expression値として分類されます。An interpolated_string_expression is classified as a value. 場合にすぐに変換されますSystem.IFormattableまたはSystem.FormattableString補間文字列の暗黙的な変換を使用 (補間文字列の変換を暗黙的な)、補間文字列式がその型。If it is immediately converted to System.IFormattable or System.FormattableString with an implicit interpolated string conversion (Implicit interpolated string conversions), the interpolated string expression has that type. それ以外の場合、型を持つstringします。Otherwise, it has the type string.

補間文字列の型が場合System.IFormattableまたはSystem.FormattableString、意味の呼び出しは、 System.Runtime.CompilerServices.FormattableStringFactory.CreateIf the type of an interpolated string is System.IFormattable or System.FormattableString, the meaning is a call to System.Runtime.CompilerServices.FormattableStringFactory.Create. 型の場合string、式の意味はへの呼び出しstring.Formatします。If the type is string, the meaning of the expression is a call to string.Format. どちらの場合も、呼び出しの引数リストは、各補間のプレース ホルダーと引数のプレース ホルダーに対応する各式のリテラル書式指定文字列で構成されます。In both cases, the argument list of the call consists of a format string literal with placeholders for each interpolation, and an argument for each expression corresponding to the place holders.

形式の文字列リテラルは、次のように構築された、Nで補間の数が、 interpolated_string_expression:The format string literal is constructed as follows, where N is the number of interpolations in the interpolated_string_expression:

  • 場合、 interpolated_regular_string_wholeまたはinterpolated_verbatim_string_wholeに依存して、$形式の文字列リテラルはそのトークンに署名します。If an interpolated_regular_string_whole or an interpolated_verbatim_string_whole follows the $ sign, then the format string literal is that token.
  • それ以外の場合、リテラルの書式指定文字列で構成されます。Otherwise, the format string literal consists of:
    • 最初、 interpolated_regular_string_startまたはinterpolated_verbatim_string_startFirst the interpolated_regular_string_start or interpolated_verbatim_string_start
    • 各数値しIから0N-1:Then for each number I from 0 to N-1:
      • 10 進表記 IThe decimal representation of I
      • 場合、対応する補間が、 constant_expression,の値の 10 進表記 (コンマ) 後に、 constant_expressionThen, if the corresponding interpolation has a constant_expression, a , (comma) followed by the decimal representation of the value of the constant_expression
      • 次に、 interpolated_regular_string_midinterpolated_regular_string_endinterpolated_verbatim_string_midまたはinterpolated_verbatim_string_end直後に対応する補間します。Then the interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_mid or interpolated_verbatim_string_end immediately following the corresponding interpolation.

後続の引数は単に、から、補間(ある場合) の順序で。The subsequent arguments are simply the expressions from the interpolations (if any), in order.

TODO: 例。TODO: examples.

単純な名前Simple names

A simple_name型引数リストが続く必要に応じて、識別子で構成されます。A simple_name consists of an identifier, optionally followed by a type argument list:

simple_name
    : identifier type_argument_list?
    ;

A simple_name形式のいずれかですIまたはフォームのI<A1,...,Ak>ここで、Iは、単一の識別子と<A1,...,Ak>は省略可能なtype_argument_listします。A simple_name is either of the form I or of the form I<A1,...,Ak>, where I is a single identifier and <A1,...,Ak> is an optional type_argument_list. ない場合type_argument_listが指定するを検討してくださいKを 0 にします。When no type_argument_list is specified, consider K to be zero. Simple_nameが評価され、次のように分類されます。The simple_name is evaluated and classified as follows:

  • 場合Kは 0 です、 simple_name内に表示する、ブロック場合に、ブロックの (または、それを囲むブロックの) ローカル変数の宣言領域 (宣言) ローカル変数、パラメーターまたは名前の定数を含む Isimple_name 、そのローカル変数を参照パラメーターまたは定数、変数または値として分類されます。If K is zero and the simple_name appears within a block and if the block's (or an enclosing block's) local variable declaration space (Declarations) contains a local variable, parameter or constant with name I, then the simple_name refers to that local variable, parameter or constant and is classified as a variable or value.

  • 場合Kゼロ、 simple_nameジェネリック メソッドの宣言の本文内に表示し、その宣言には、名前の型パラメーターが含まれている場合 Isimple_nameその型パラメーターを参照します。If K is zero and the simple_name appears within the body of a generic method declaration and if that declaration includes a type parameter with name I, then the simple_name refers to that type parameter.

  • それ以外の場合、各インスタンス タイプ T(インスタンス型)、すぐ外側の型宣言のインスタンスの型を起動し、各外側のクラスまたは構造体のインスタンスの型を続行宣言 (ある場合):Otherwise, for each instance type T (The instance type), starting with the instance type of the immediately enclosing type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):

    • 場合Kは 0 との宣言T名前の型パラメーターを含む Isimple_nameその型パラメーターを参照します。If K is zero and the declaration of T includes a type parameter with name I, then the simple_name refers to that type parameter.
    • それ以外の場合、メンバーの検索 (メンバー ルックアップ) のITK 型引数が一致するものが生成されます。Otherwise, if a member lookup (Member lookup) of I in T with K type arguments produces a match:
      • 場合Tすぐ外側のクラスまたは構造体の型のインスタンスの型は、検索でいずれかが識別や以上のメソッドは、結果は、メソッドのグループの関連付けられたインスタンス式があるthisします。If T is the instance type of the immediately enclosing class or struct type and the lookup identifies one or more methods, the result is a method group with an associated instance expression of this. ジェネリック メソッドの呼び出しで使用される型引数リストが指定されている場合 (メソッドの呼び出し)。If a type argument list was specified, it is used in calling a generic method (Method invocations).
      • の場合Tすぐ外側のクラスまたは構造体の型のインスタンスの型は、検索は、インスタンス メンバーを識別し、インスタンス コンス トラクター、インスタンス メソッドまたはインスタンス アクセサーの本文内の参照が発生した場合、メンバー アクセスと同じになります (メンバー アクセス) フォームのthis.Iします。Otherwise, if T is the instance type of the immediately enclosing class or struct type, if the lookup identifies an instance member, and if the reference occurs within the body of an instance constructor, an instance method, or an instance accessor, the result is the same as a member access (Member access) of the form this.I. これはのみに発生時にKは 0 です。This can only happen when K is zero.
      • それ以外の場合、結果は、メンバー アクセスと同じ (メンバー アクセス) フォームのT.IまたはT.I<A1,...,Ak>します。Otherwise, the result is the same as a member access (Member access) of the form T.I or T.I<A1,...,Ak>. ここでは、バインド エラーには、 simple_nameインスタンス メンバーを参照します。In this case, it is a binding-time error for the simple_name to refer to an instance member.
  • それ以外の名前空間ごとに Nを名前空間を以降のsimple_name発生すると、次の手順は、各名前空間 (存在する場合)、および末尾に、グローバル名前空間を続行します。エンティティが見つかるまで評価されます。Otherwise, for each namespace N, starting with the namespace in which the simple_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:

    • 場合KゼロとIで名前空間の名前を指定 N、し。If K is zero and I is the name of a namespace in N, then:
      • 場合、場所をsimple_nameが発生した名前空間の宣言で囲まれたN名前空間宣言が含まれています、 extern_alias_directiveまたはusing_alias_directive名前に関連付ける I型、または名前空間、 simple_nameがあいまいですし、コンパイル時エラーが発生します。If the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
      • それ以外の場合、 simple_nameという名前の名前空間を指すINします。Otherwise, the simple_name refers to the namespace named I in N.
    • の場合N名前を持つアクセス可能な型が含まれています IK し、パラメーターを入力します。Otherwise, if N contains an accessible type having name I and K type parameters, then:
      • 場合Kは 0 と場所をsimple_nameが発生した名前空間の宣言で囲まれたN名前空間宣言が含まれています、 extern_alias_directiveまたはusing_alias_directive名前に関連付ける I型、または名前空間、 simple_nameがあいまいですし、コンパイル時エラーが発生します。If K is zero and the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
      • それ以外の場合、 namespace_or_type_nameは特定の型引数を使用して構築型を表します。Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
    • の場合、場所を、 simple_nameが発生した名前空間の宣言で囲まれた N:Otherwise, if the location where the simple_name occurs is enclosed by a namespace declaration for N:
      • 場合Kがゼロで、名前空間宣言が含まれています、 extern_alias_directiveまたはusing_alias_directive名前に関連付ける Iでインポートされた名前空間または型、 simple_nameその名前空間または型を参照します。If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the simple_name refers to that namespace or type.
      • それ以外の場合、名前空間と型の宣言をインポートした場合、 using_namespace_directives とusing_static_directive名前空間宣言の s がアクセス可能な型の 1 つだけを含めるか、拡張機能の非静的メンバーの名前を持つ IK パラメーター、入力、 simple_name参照すると、その型またはメンバーの型引数を使用して構築します。Otherwise, if the namespaces and type declarations imported by the using_namespace_directives and using_static_directives of the namespace declaration contain exactly one accessible type or non-extension static member having name I and K type parameters, then the simple_name refers to that type or member constructed with the given type arguments.
      • それ以外の場合、名前空間と型をインポートした場合、 using_namespace_directive名前空間の宣言の 1 つ以上のアクセス可能な型または名前を持つ拡張メソッドでは非静的メンバーを含む IK パラメーター、入力、 simple_nameがあいまい、エラーが発生します。Otherwise, if the namespaces and types imported by the using_namespace_directives of the namespace declaration contain more than one accessible type or non-extension-method static member having name I and K type parameters, then the simple_name is ambiguous and an error occurs.

    この全体の手順では、対応する手順の処理中に完全に並列に注意してください、 namespace_or_type_name (Namespace と型の名前)。Note that this entire step is exactly parallel to the corresponding step in the processing of a namespace_or_type_name (Namespace and type names).

  • それ以外の場合、 simple_nameは未定義となり、コンパイル時エラーが発生します。Otherwise, the simple_name is undefined and a compile-time error occurs.

かっこで囲まれた式Parenthesized expressions

A parenthesized_expressionから成る、かっこで囲まれています。A parenthesized_expression consists of an expression enclosed in parentheses.

parenthesized_expression
    : '(' expression ')'
    ;

A parenthesized_expressionは評価することによって評価されます、かっこで囲まれています。A parenthesized_expression is evaluated by evaluating the expression within the parentheses. 場合、かっこで囲ま表します名前空間または型、コンパイル時エラーが発生します。If the expression within the parentheses denotes a namespace or type, a compile-time error occurs. それ以外の場合の結果、 parenthesized_expressionの格納されている評価の結果は、します。Otherwise, the result of the parenthesized_expression is the result of the evaluation of the contained expression.

メンバー アクセス。Member access

A member_accessから成る、 primary_expressionpredefined_type、またはqualified_alias_member"と、その後."トークン、その後に、識別子、必要に応じてその後に、 type_argument_listします。A member_access consists of a primary_expression, a predefined_type, or a qualified_alias_member, followed by a "." token, followed by an identifier, optionally followed by a type_argument_list.

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

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

Qualified_alias_memberで定義されている運用Namespace エイリアス修飾子します。The qualified_alias_member production is defined in Namespace alias qualifiers.

A member_access形式のいずれかですE.IまたはフォームのE.I<A1, ..., Ak>ここで、Eプライマリ式は、Iは、単一の識別子と<A1, ..., Ak>は省略可能なtype_argument_listします。A member_access is either of the form E.I or of the form E.I<A1, ..., Ak>, where E is a primary-expression, I is a single identifier and <A1, ..., Ak> is an optional type_argument_list. ない場合type_argument_listが指定するを検討してくださいKを 0 にします。When no type_argument_list is specified, consider K to be zero.

A member_accessで、 primary_expression型のdynamicが動的にバインドされている (動的バインド)。A member_access with a primary_expression of type dynamic is dynamically bound (Dynamic binding). ここで、コンパイラが型のプロパティ アクセスにメンバー アクセスを分類dynamicします。In this case the compiler classifies the member access as a property access of type dynamic. 意味を調べるには、次の規則、 member_accessランタイムのコンパイル時の型ではなく、実行時の型を使用するのには、適用、 primary_expressionします。The rules below to determine the meaning of the member_access are then applied at run-time, using the run-time type instead of the compile-time type of the primary_expression. このランタイムの分類は、メソッド グループにつながるかどうかは、メンバー アクセスである必要があります、 primary_expressioninvocation_expressionします。If this run-time classification leads to a method group, then the member access must be the primary_expression of an invocation_expression.

Member_accessが評価され、次のように分類されます。The member_access is evaluated and classified as follows:

  • 場合KゼロとE名前空間とE入れ子になった名前空間が含まれています I、結果はその名前空間。If K is zero and E is a namespace and E contains a nested namespace with name I, then the result is that namespace.
  • の場合E名前空間とE名前を持つアクセス可能な型が含まれています IK  、結果は指定された型引数で構築された型のパラメーターを入力します。Otherwise, if E is a namespace and E contains an accessible type having name I and K type parameters, then the result is that type constructed with the given type arguments.
  • 場合Eは、 predefined_typeまたはprimary_expression場合は、型に分類Eが型パラメーターでない場合、メンバーの検索 (メンバー ルックアップ)IEK し、型パラメーターに一致するが生成されますE.Iが評価され、次のように分類されます。If E is a predefined_type or a primary_expression classified as a type, if E is not a type parameter, and if a member lookup (Member lookup) of I in E with K type parameters produces a match, then E.I is evaluated and classified as follows:
    • 場合I結果はその型指定された型引数を使用して構築型を識別します。If I identifies a type, then the result is that type constructed with the given type arguments.
    • 場合I結果は関連付けられたインスタンス式を指定せずに、メソッド グループに 1 つまたは複数のメソッドを識別します。If I identifies one or more methods, then the result is a method group with no associated instance expression. ジェネリック メソッドの呼び出しで使用される型引数リストが指定されている場合 (メソッドの呼び出し)。If a type argument list was specified, it is used in calling a generic method (Method invocations).
    • 場合I識別、staticプロパティ、結果は、プロパティへのアクセスに関連付けられたインスタンス式がありません。If I identifies a static property, then the result is a property access with no associated instance expression.
    • 場合I識別、staticフィールド。If I identifies a static field:
      • フィールドの場合readonlyクラスまたは構造体のフィールドが宣言されているの静的コンス トラクターの外部参照が発生し、結果は、値、つまり静的フィールドの値と Iで Eします。If the field is readonly and the reference occurs outside the static constructor of the class or struct in which the field is declared, then the result is a value, namely the value of the static field I in E.
      • それ以外の場合、結果は、変数、静的フィールド namely Iで Eします。Otherwise, the result is a variable, namely the static field I in E.
    • 場合I識別、staticイベント。If I identifies a static event:
      • クラスまたは構造体をイベントを宣言し、イベントなしで宣言された参照が発生したかどうかevent_accessor_declarations (イベント)、しE.Iが正確に処理されます。まるでIスタティック フィールドします。If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), then E.I is processed exactly as if I were a static field.
      • それ以外の場合、関連付けられたインスタンス式を指定イベント アクセスになりません。Otherwise, the result is an event access with no associated instance expression.
    • 場合I結果は、値、つまりその定数の値に定数を識別します。If I identifies a constant, then the result is a value, namely the value of that constant.
    • 場合I結果は、値、つまりその列挙体メンバーの値を列挙メンバーを識別します。If I identifies an enumeration member, then the result is a value, namely the value of that enumeration member.
    • それ以外の場合、E.I無効なメンバー参照であり、コンパイル時エラーが発生します。Otherwise, E.I is an invalid member reference, and a compile-time error occurs.
  • 場合Eプロパティへのアクセス、インデクサーのアクセス、変数、または、型が値 T、およびメンバーの検索 (メンバー ルックアップ) のITK  型引数をし、一致する生成E.Iが評価され、次のように分類されます。If E is a property access, indexer access, variable, or value, the type of which is T, and a member lookup (Member lookup) of I in T with K type arguments produces a match, then E.I is evaluated and classified as follows:
    • 最初に、場合Eプロパティまたはインデクサーのアクセスは、プロパティの値またはインデクサー アクセスが取得される (式の値) とE値として再分類します。First, if E is a property or indexer access, then the value of the property or indexer access is obtained (Values of expressions) and E is reclassified as a value.
    • 場合I、結果は、メソッドのグループの関連付けられたインスタンス式が 1 つまたは複数のメソッドを識別するEします。If I identifies one or more methods, then the result is a method group with an associated instance expression of E. ジェネリック メソッドの呼び出しで使用される型引数リストが指定されている場合 (メソッドの呼び出し)。If a type argument list was specified, it is used in calling a generic method (Method invocations).
    • 場合Iインスタンス プロパティを識別します。If I identifies an instance property,
      • 場合EthisI 、自動的に実装されたプロパティを識別します (自動実装プロパティ) のインスタンス コンス トラクター内で set アクセス操作子、および参照が発生せず、クラスまたは構造体型T、結果は、変数によって指定される自動プロパティの非表示のバッキング フィールド namelyIのインスタンスでTによって指定されたthisします。If E is this, I identifies an automatically implemented property (Automatically implemented properties) without a setter, and the reference occurs within an instance constructor for a class or struct type T, then the result is a variable, namely the hidden backing field for the auto-property given by I in the instance of T given by this.
      • 結果の式が関連付けられているインスタンスのプロパティ アクセスは、それ以外の場合、 Eします。Otherwise, the result is a property access with an associated instance expression of E.
    • 場合Tは、 class_typeIのインスタンス フィールドを識別するclass_type:If T is a class_type and I identifies an instance field of that class_type:
      • 場合の値EnullSystem.NullReferenceExceptionがスローされます。If the value of E is null, then a System.NullReferenceException is thrown.
      • それ以外の場合、フィールドの場合readonlyフィールドが宣言されているクラスのインスタンス コンス トラクターの外部参照が発生し、結果は、値、つまり、フィールドの値と Iによって参照されるオブジェクトで Eします。Otherwise, if the field is readonly and the reference occurs outside an instance constructor of the class in which the field is declared, then the result is a value, namely the value of the field I in the object referenced by E.
      • それ以外の場合、結果は、変数、つまりフィールド Iによって参照されるオブジェクトで Eします。Otherwise, the result is a variable, namely the field I in the object referenced by E.
    • 場合Tは、 struct_typeIのインスタンス フィールドを識別するstruct_type:If T is a struct_type and I identifies an instance field of that struct_type:
      • 場合E、値は、フィールドの場合、またはreadonlyフィールドが宣言されている構造体のインスタンス コンス トラクターの外部参照が発生し、結果は、値、つまり、フィールドの値と Iで指定された構造体のインスタンスで E.If E is a value, or if the field is readonly and the reference occurs outside an instance constructor of the struct in which the field is declared, then the result is a value, namely the value of the field I in the struct instance given by E.
      • それ以外の場合、結果は、変数、つまりフィールド Iで指定された構造体のインスタンスで Eします。Otherwise, the result is a variable, namely the field I in the struct instance given by E.
    • 場合Iインスタンス イベントを識別します。If I identifies an instance event:
      • クラスまたは構造体をイベントを宣言し、イベントなしで宣言された参照が発生したかどうかevent_accessor_declarations (イベント) に、参照が発生しないと、左側にある、+=または-=演算子、E.Iが正確に処理される場合とIされたインスタンス フィールド。If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), and the reference does not occur as the left-hand side of a += or -= operator, then E.I is processed exactly as if I was an instance field.
      • それ以外の場合、結果は、イベントの関連付けられたインスタンス式があるアクセス Eします。Otherwise, the result is an event access with an associated instance expression of E.
  • それ以外の場合、しようとしましたが処理E.I拡張メソッド呼び出しとして (拡張メソッド呼び出し)。Otherwise, an attempt is made to process E.I as an extension method invocation (Extension method invocations). これが失敗すると、E.I無効なメンバー参照であり、バインド時のエラーが発生します。If this fails, E.I is an invalid member reference, and a binding-time error occurs.

同一の簡易名と型名Identical simple names and type names

形式のメンバー アクセスでE.I場合は、 E 、単一の識別子は、場合の意味Eとして、 simple_name (簡易名) 定数、フィールド、プロパティ、ローカル変数またはパラメーターの意味と同じ型とEとして、 type_name (Namespace と型の名前)、しの両方の可能性のある意味Eは許可されています。In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple_name (Simple names) is a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type_name (Namespace and type names), then both possible meanings of E are permitted. 2 つの可能性のある意味E.Iされないため、あいまいなI型のメンバーであるとは限りませんEどちらの場合もします。The two possible meanings of E.I are never ambiguous, since I must necessarily be a member of the type E in both cases. つまり、ルールだけアクセスを許可する静的メンバーと入れ子にされた型のEコンパイル時エラーが発生した、それ以外の場合。In other words, the rule simply permits access to the static members and nested types of E where a compile-time error would otherwise have occurred. 例:For example:

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

    public Color Complement() {...}
}

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

    void F() {
        Color = Color.Black;           // References Color.Black static member
        Color = Color.Complement();    // Invokes Complement() on Color field
    }

    static void G() {
        Color c = Color.White;         // References Color.White static member
    }
}

文法のあいまいさGrammar ambiguities

生産simple_name (簡易名) とmember_access (メンバー アクセス) のあいまいさを得ることができます、式の文法。The productions for simple_name (Simple names) and member_access (Member access) can give rise to ambiguities in the grammar for expressions. たとえば、次のようなステートメントがあるとします。For example, the statement:

F(G<A,B>(7));

呼び出しとして解釈される可能性F、2 つの引数でG < AB > (7)します。could be interpreted as a call to F with two arguments, G < A and B > (7). 呼び出しとしても解釈される可能性F1 つの引数はジェネリック メソッドの呼び出し G2 つの型引数と 1 つの通常の引数。Alternatively, it could be interpreted as a call to F with one argument, which is a call to a generic method G with two type arguments and one regular argument.

トークンのシーケンスを (コンテキストで) として解析できるかどうか、 simple_name (簡易名)、 member_access (メンバー アクセス)、またはpointer_member_access (ポインターのメンバー アクセス) で終わる、 type_argument_list (引数を入力)、トークンの終了の直後に続く>トークンが調べられます。If a sequence of tokens can be parsed (in context) as a simple_name (Simple names), member_access (Member access), or pointer_member_access (Pointer member access) ending with a type_argument_list (Type arguments), the token immediately following the closing > token is examined. いずれかである場合If it is one of

(  )  ]  }  :  ;  ,  .  ?  ==  !=  |  ^

次に、 type_argument_listはの一部として保持され、 simple_namemember_accessまたはpointer_member_accessと、トークンのシーケンスの考えられるその他の解析は破棄されます。then the type_argument_list is retained as part of the simple_name, member_access or pointer_member_access and any other possible parse of the sequence of tokens is discarded. それ以外の場合、 type_argument_listの一部であるとは見なされません、 simple_namemember_accessまたはpointer_member_accessトークンのシーケンスの考えられるその他の解析がない場合でも、します。Otherwise, the type_argument_list is not considered to be part of the simple_name, member_access or pointer_member_access, even if there is no other possible parse of the sequence of tokens. 解析するときに、これらの規則がないので注意が適用される、 type_argument_listで、 namespace_or_type_name (Namespace と型の名前)。Note that these rules are not applied when parsing a type_argument_list in a namespace_or_type_name (Namespace and type names). 次のステートメント、The statement

F(G<A,B>(7));

このルールに従って解釈されますへの呼び出しとしてF1 つの引数はジェネリック メソッドの呼び出しG2 つの型引数と 1 つの通常の引数。will, according to this rule, be interpreted as a call to F with one argument, which is a call to a generic method G with two type arguments and one regular argument. ステートメントThe statements

F(G < A, B > 7);
F(G < A, B >> 7);

呼び出しとして解釈されます各F2 つの引数を使用します。will each be interpreted as a call to F with two arguments. 次のステートメント、The statement

x = F < A > +y;

ステートメントを記述した場合と、小なり演算子、演算子と単項プラス演算子よりも大きいと解釈されますx = (F < A) > (+y)の代わりとして、 simple_nameで、 type_argument_list二項プラス演算子を続けています。will be interpreted as a less than operator, greater than operator, and unary plus operator, as if the statement had been written x = (F < A) > (+y), instead of as a simple_name with a type_argument_list followed by a binary plus operator. ステートメントでIn the statement

x = y is C<T> + z;

トークンC<T>として解釈されます、 namespace_or_type_nameで、 type_argument_listします。the tokens C<T> are interpreted as a namespace_or_type_name with a type_argument_list.

Invocation 式Invocation expressions

Invocation_expressionメソッドを呼び出すために使用します。An invocation_expression is used to invoke a method.

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

Invocation_expressionが動的にバインドされている (動的バインド)、次の少なくとも 1 つ保持している場合。An invocation_expression is dynamically bound (Dynamic binding) if at least one of the following holds:

  • Primary_expressionコンパイル時の型を持つdynamicします。The primary_expression has compile-time type dynamic.
  • オプションの少なくとも 1 つの引数argument_listコンパイル時の型を持つdynamicprimary_expressionデリゲート型がありません。At least one argument of the optional argument_list has compile-time type dynamic and the primary_expression does not have a delegate type.

この場合、コンパイラは、分類、 invocation_expression型の値としてdynamicします。In this case the compiler classifies the invocation_expression as a value of type dynamic. 意味を調べるには、次の規則、 invocation_expression実行時、のコンパイル時の型ではなく、実行時の型を使用するのには、適用、 primary_expressionとコンパイル時の型引数dynamicします。The rules below to determine the meaning of the invocation_expression are then applied at run-time, using the run-time type instead of the compile-time type of those of the primary_expression and arguments which have the compile-time type dynamic. 場合、 primary_expressionコンパイル時の型がdynamic、メソッドの呼び出しで」の説明に従って、制限付きのコンパイル時のチェックが行われ、コンパイル時の動的なオーバー ロードの解決の確認.If the primary_expression does not have compile-time type dynamic, then the method invocation undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

Primary_expressioninvocation_expressionメソッド グループ、またはの値にする必要があります、 delegate_typeします。The primary_expression of an invocation_expression must be a method group or a value of a delegate_type. 場合、 primary_expression 、メソッド グループには、 invocation_expressionメソッドの呼び出しは、(メソッドの呼び出し)。If the primary_expression is a method group, the invocation_expression is a method invocation (Method invocations). 場合、 primary_expressionの値であり、 delegate_typeinvocation_expressionデリゲートの呼び出しは、(デリゲートの呼び出し).If the primary_expression is a value of a delegate_type, the invocation_expression is a delegate invocation (Delegate invocations). 場合、 primary_expressionはメソッド グループでの値も、 delegate_type、バインド エラーが発生します。If the primary_expression is neither a method group nor a value of a delegate_type, a binding-time error occurs.

省略可能なargument_list (引数リスト) メソッドのパラメーター値または変数参照を提供します。The optional argument_list (Argument lists) provides values or variable references for the parameters of the method.

評価した結果、 invocation_expression次のように分類されます。The result of evaluating an invocation_expression is classified as follows:

  • 場合、 invocation_expressionメソッドまたはを返すデリゲートが呼び出されるvoid結果はありません。If the invocation_expression invokes a method or delegate that returns void, the result is nothing. コンテキストでのみ許可されているが何に分類される式をstatement_expression (式ステートメント) またはの本文として、 lambda_expression(匿名関数式)。An expression that is classified as nothing is permitted only in the context of a statement_expression (Expression statements) or as the body of a lambda_expression (Anonymous function expressions). それ以外の場合、バインド時のエラーが発生します。Otherwise a binding-time error occurs.
  • それ以外の場合、メソッドまたはデリゲートによって返される型の値になります。Otherwise, the result is a value of the type returned by the method or delegate.

メソッドの呼び出しMethod invocations

メソッドの呼び出し、 primary_expressioninvocation_expressionメソッド グループである必要があります。For a method invocation, the primary_expression of the invocation_expression must be a method group. メソッド グループでは、1 つのメソッドを呼び出すまたは特定のメソッドを呼び出すを選択できるオーバー ロードされたメソッドのセットを識別します。The method group identifies the one method to invoke or the set of overloaded methods from which to choose a specific method to invoke. 後者の場合、呼び出す特定のメソッドの決定は、引数の型によって提供されるコンテキストに基づきます、 argument_listします。In the latter case, determination of the specific method to invoke is based on the context provided by the types of the arguments in the argument_list.

フォームのメソッドの呼び出しのバインド時の処理M(A)ここで、Mメソッド グループ (を含めることも、 type_argument_list)、およびAは省略可能なargument_リスト、次の手順で構成されます。The binding-time processing of a method invocation of the form M(A), where M is a method group (possibly including a type_argument_list), and A is an optional argument_list, consists of the following steps:

  • メソッドの呼び出しの候補のメソッドのセットが構築されます。The set of candidate methods for the method invocation is constructed. 各メソッドのFメソッド グループに関連付けられたM:For each method F associated with the method group M:
    • 場合F非ジェネリック型F候補とき。If F is non-generic, F is a candidate when:
    • 場合FがジェネリックとM型引数のリストを持たないF候補とき。If F is generic and M has no type argument list, F is a candidate when:
      • 型の推論 (型推論) 成功すると、呼び出し、型引数の一覧への推論とType inference (Type inference) succeeds, inferring a list of type arguments for the call, and
      • F のパラメーター リストですべて構築された型が、その制約を満たす、推論された型引数は、対応するメソッドの型パラメーターに置き換え、(制約条件を満たす)、およびのパラメーターのリストFを適用できるA(適用可能な関数メンバー)。Once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
    • 場合FジェネリックとM型引数リストが含まれていますF候補とき。If F is generic and M includes a type argument list, F is a candidate when:
      • F 型引数リストで指定されたメソッド型パラメーターの同じ番号を持つとF has the same number of method type parameters as were supplied in the type argument list, and
      • F のパラメーター リストですべて構築された型が、その制約を満たす型引数は、対応するメソッドの型パラメーターに置き換え、(制約条件を満たす)、およびパラメーター リストのF適用できるA(適用可能な関数メンバー)。Once the type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
  • 候補メソッドのセットは、最派生型からのみを含むに縮小されます。各メソッドのC.F、セット内でCの種類は、メソッドFの基本型で宣言されているすべてのメソッド宣言Cセットから削除されます。The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set. さらに場合、Cクラス型は他にも、objectインターフェイス型で宣言されているすべてのメソッドは、セットから削除されます。Furthermore, if C is a class type other than object, all methods declared in an interface type are removed from the set. (この後者の規則のみが影響メソッド グループがオブジェクト以外の有効な基本クラスと、空でない有効なインターフェイス セットを持つ型パラメーターでメンバーの検索の結果です。)(This latter rule only has affect when the method group was the result of a member lookup on a type parameter having an effective base class other than object and a non-empty effective interface set.)
  • 候補メソッドの結果セットが空の場合は、さらに、次の手順に沿った処理は中止され、代わりに試行されると、呼び出しを拡張メソッド呼び出しとして処理する (拡張メソッド呼び出し).If the resulting set of candidate methods is empty, then further processing along the following steps are abandoned, and instead an attempt is made to process the invocation as an extension method invocation (Extension method invocations). これが失敗した場合、適用可能なメソッドが存在していないため、し、バインド エラーが発生します。If this fails, then no applicable methods exist, and a binding-time error occurs.
  • オーバー ロード解決規則を使用して候補メソッドのセットの最適な方法が識別されるオーバー ロードの解決します。The best method of the set of candidate methods is identified using the overload resolution rules of Overload resolution. 、1 つの最適な方法を識別できない場合、メソッドの呼び出しはあいまいであり、バインド エラーが発生します。If a single best method cannot be identified, the method invocation is ambiguous, and a binding-time error occurs. オーバー ロードの解決を実行するには、対応するメソッドの型パラメーターのジェネリック メソッドのパラメーターが型引数 (指定または推論) を代入した後と見なされます。When performing overload resolution, the parameters of a generic method are considered after substituting the type arguments (supplied or inferred) for the corresponding method type parameters.
  • 選択した最適な方法の最終的な検証が実行されます。Final validation of the chosen best method is performed:
    • メソッドは、メソッド グループのコンテキストで検証されます。最適な方法が静的メソッドの場合、メソッド グループが得、 simple_nameまたはmember_access型を通じてします。The method is validated in the context of the method group: If the best method is a static method, the method group must have resulted from a simple_name or a member_access through a type. 最適な方法が、インスタンス メソッドの場合、メソッド グループが得、 simple_namemember_access変数または値、またはbase_accessします。If the best method is an instance method, the method group must have resulted from a simple_name, a member_access through a variable or value, or a base_access. これらの要件のどちらが true の場合、バインド時のエラーが発生します。If neither of these requirements is true, a binding-time error occurs.
    • (指定または推論) の型引数が制約に照らしてチェックが最適なメソッドがジェネリック メソッドの場合 (制約条件を満たす) ジェネリック メソッドで宣言します。If the best method is a generic method, the type arguments (supplied or inferred) are checked against the constraints (Satisfying constraints) declared on the generic method. すべての型引数が、型パラメーターに対応する制約を満たしていない場合、バインド時のエラーが発生します。If any type argument does not satisfy the corresponding constraint(s) on the type parameter, a binding-time error occurs.

説明されている関数メンバーの呼び出しの規則に従って実行時の実際の呼び出しを処理するメソッドを選択し、上記の手順によって、バインド時に検証されましたが、コンパイル時の動的なオーバー ロードの解決の確認.Once a method has been selected and validated at binding-time by the above steps, the actual run-time invocation is processed according to the rules of function member invocation described in Compile-time checking of dynamic overload resolution.

上記で説明した解決ルールの直感的な影響は次のとおりです。メソッドの呼び出しによって起動される特定のメソッドを検索するにはメソッドの呼び出しで示される型で始めて、少なくとも 1 つの適用可能なアクセス可能なオーバーライドではないメソッドの宣言が見つかるまで、継承チェーンを続行できます。The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. 型の推定を実行しオーバー ロードの解決では、その型で宣言されている適用可能なアクセス可能なオーバーライドではないメソッドのセットと、選択されているため、メソッドを呼び出します。Then perform type inference and overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected. メソッドが見つからなかった場合は、呼び出しを拡張メソッド呼び出しとして処理する代わりにしてください。If no method was found, try instead to process the invocation as an extension method invocation.

拡張メソッドの呼び出しExtension method invocations

メソッドの呼び出しで (ボックス化されたインスタンス上の呼び出し)、フォームの 1 つのIn a method invocation (Invocations on boxed instances) of one of the forms

expr . identifier ( )

expr . identifier ( args )

expr . identifier < typeargs > ( )

expr . identifier < typeargs > ( args )

呼び出しの通常の処理に適用可能なメソッドが検出されない場合、拡張メソッドの呼び出しとして構造の処理を試行します。if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. 場合exprまたはのいずれか、 argsコンパイル時の型を持つdynamic、拡張メソッドは適用されません。If expr or any of the args has compile-time type dynamic, extension methods will not apply.

目的は、一番type_name C、対応する静的メソッド呼び出しを実行できるようにします。The objective is to find the best type_name C, so that the corresponding static method invocation can take place:

C . identifier ( expr )

C . identifier ( expr , args )

C . identifier < typeargs > ( expr )

C . identifier < typeargs > ( expr , args )

拡張メソッドCi.Mj対象となる場合。An extension method Ci.Mj is eligible if:

  • Ci 非ジェネリックの入れ子になっていないクラスCi is a non-generic, non-nested class
  • 名前Mj識別子The name of Mj is identifier
  • Mj アクセス可能で、上記のように、引数に静的メソッドとして適用されるときに適用できます。Mj is accessible and applicable when applied to the arguments as a static method as shown above
  • 暗黙的な id、参照変換またはボックス化変換が存在するexprの最初のパラメーターの型にMjします。An implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.

検索C次のように進みます。The search for C proceeds as follows:

  • 以降、それを囲む各名前空間宣言を続行し、コンパイル単位で終わるの最も近いの外側の名前空間宣言での拡張メソッドの候補セットを連続する試行が行われます。Starting with the closest enclosing namespace declaration, continuing with each enclosing namespace declaration, and ending with the containing compilation unit, successive attempts are made to find a candidate set of extension methods:
    • 指定された名前空間またはコンパイル ユニットに直接汎用でない型宣言が含まれるかどうかCi資格のある拡張メソッドでMj、それらの拡張メソッドのセットは、候補の集合です。If the given namespace or compilation unit directly contains non-generic type declarations Ci with eligible extension methods Mj, then the set of those extension methods is the candidate set.
    • 場合型Ciによってインポートされたusing_static_declarationsによってインポートされた名前空間で直接宣言とusing_namespace_directiveで指定された名前空間またはコンパイル ユニットを直接 s対象となる拡張メソッドを含むMj、それらの拡張メソッドのセットは、候補の集合。If types Ci imported by using_static_declarations and directly declared in namespaces imported by using_namespace_directives in the given namespace or compilation unit directly contain eligible extension methods Mj, then the set of those extension methods is the candidate set.
  • それを囲む名前空間の宣言またはコンパイル単位の候補のセットが見つからない場合は、コンパイル時エラーが発生します。If no candidate set is found in any enclosing namespace declaration or compilation unit, a compile-time error occurs.
  • 示すように設定する候補にオーバー ロードの解決を適用する場合は、(オーバー ロードの解決)。Otherwise, overload resolution is applied to the candidate set as described in (Overload resolution). 1 つの最適な方法が見つからない場合は、コンパイル時エラーが発生します。If no single best method is found, a compile-time error occurs.
  • C 拡張メソッドとして最適な方法を宣言する型です。C is the type within which the best method is declared as an extension method.

使用してC静的メソッドの呼び出しとして処理し、メソッドの呼び出しのターゲットとして (コンパイル時の動的なオーバー ロードの解決チェック)。Using C as a target, the method call is then processed as a static method invocation (Compile-time checking of dynamic overload resolution).

インスタンス メソッドが拡張メソッドより優先順位を取得、拡張メソッドの内部名前空間の宣言で使用可能な優先される拡張メソッドの外部名前空間の宣言、およびその拡張機能で使用できるという意味で、上記の規則名前空間で直接宣言されたメソッドを使用して、その同じ空間にインポートされた拡張メソッドよりも優先名前空間ディレクティブ。The preceding rules mean that instance methods take precedence over extension methods, that extension methods available in inner namespace declarations take precedence over extension methods available in outer namespace declarations, and that extension methods declared directly in a namespace take precedence over extension methods imported into that same namespace with a using namespace directive. 例:For example:

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のメソッドが両方の拡張メソッドより優先されます。In the example, B's method takes precedence over the first extension method, and C's method takes precedence over both extension methods.

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

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

namespace N2
{
    using N1;

    public static class E
    {
        public static void F(this int i) { Console.WriteLine("E.F({0})", i); }
    }

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

この例の出力は次のとおりです。The output of this example is:

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

D.G も優先C.G、およびE.F両方よりも優先D.FC.Fします。D.G takes precedence over C.G, and E.F takes precedence over both D.F and C.F.

デリゲートの呼び出しDelegate invocations

デリゲートの呼び出しのprimary_expressioninvocation_expressionの値を指定する必要があります、 delegate_typeします。For a delegate invocation, the primary_expression of the invocation_expression must be a value of a delegate_type. さらに、検討、 delegate_typeと同じパラメーター リストを持つ関数メンバーである、 delegate_typedelegate_type (該当する必要があります適用可能な関数メンバー) をargument_listinvocation_expressionします。Furthermore, considering the delegate_type to be a function member with the same parameter list as the delegate_type, the delegate_type must be applicable (Applicable function member) with respect to the argument_list of the invocation_expression.

フォームのデリゲートの呼び出しの実行時の処理D(A)ここで、Dは、 primary_expressiondelegate_typeAは省略可能なargument_list、次の手順で構成されます。The run-time processing of a delegate invocation of the form D(A), where D is a primary_expression of a delegate_type and A is an optional argument_list, consists of the following steps:

  • D 評価されます。D is evaluated. この評価は、例外を発生させ、その後の手順は実行されません。If this evaluation causes an exception, no further steps are executed.
  • Dがチェックを有効にします。The value of D is checked to be valid. 場合の値DnullSystem.NullReferenceExceptionがスローされます、以降の手順は実行されません。If the value of D is null, a System.NullReferenceException is thrown and no further steps are executed.
  • それ以外の場合、Dデリゲート インスタンスへの参照です。Otherwise, D is a reference to a delegate instance. 関数メンバーの呼び出し (コンパイル時の動的なオーバー ロードの解決チェック) の各デリゲートの呼び出しリストで呼び出し可能なエンティティで実行されます。Function member invocations (Compile-time checking of dynamic overload resolution) are performed on each of the callable entities in the invocation list of the delegate. 呼び出し可能なエンティティのインスタンスとインスタンス メソッドで構成される場合は、特定の呼び出しのインスタンスは、呼び出し可能なエンティティに含まれているインスタンスです。For callable entities consisting of an instance and instance method, the instance for the invocation is the instance contained in the callable entity.

要素へのアクセスElement access

Element_accessから成る、 primary_no_array_creation_expression、その後に、"["トークン、その後に、 argument_list、その後に、"]"トークンです。An element_access consists of a primary_no_array_creation_expression, followed by a "[" token, followed by an argument_list, followed by a "]" token. Argument_list 1 つまたは複数から成る引数s、コンマで区切られました。The argument_list consists of one or more arguments, separated by commas.

element_access
    : primary_no_array_creation_expression '[' expression_list ']'
    ;

Argument_listelement_accessを格納することはできませんrefまたはout引数。The argument_list of an element_access is not allowed to contain ref or out arguments.

Element_accessが動的にバインドされている (動的バインド)、次の少なくとも 1 つ保持している場合。An element_access is dynamically bound (Dynamic binding) if at least one of the following holds:

  • Primary_no_array_creation_expressionコンパイル時の型を持つdynamicします。The primary_no_array_creation_expression has compile-time type dynamic.
  • 少なくとも 1 つの式、 argument_listコンパイル時の型を持つdynamicprimary_no_array_creation_expression配列型はありません。At least one expression of the argument_list has compile-time type dynamic and the primary_no_array_creation_expression does not have an array type.

この場合、コンパイラは、分類、 element_access型の値としてdynamicします。In this case the compiler classifies the element_access as a value of type dynamic. 意味を調べるには、次の規則、 element_access実行時、のコンパイル時の型ではなく、実行時の型を使用するのには、適用、 primary_no_array_creation_expressionargument_listコンパイル時の型を持つことが式dynamicします。The rules below to determine the meaning of the element_access are then applied at run-time, using the run-time type instead of the compile-time type of those of the primary_no_array_creation_expression and argument_list expressions which have the compile-time type dynamic. 場合、 primary_no_array_creation_expressionコンパイル時の型がdynamic、」の説明に従って、要素へのアクセスが制限付きのコンパイル時のチェックを受けて、コンパイル時の動的なチェックオーバー ロードの解決します。If the primary_no_array_creation_expression does not have compile-time type dynamic, then the element access undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

場合、 primary_no_array_creation_expressionelement_accessの値であり、 array_typeelement_accessが、配列のアクセス (配列アクセス)。If the primary_no_array_creation_expression of an element_access is a value of an array_type, the element_access is an array access (Array access). それ以外の場合、 primary_no_array_creation_expression変数またはクラス、構造体、またはインターフェイスの種類を 1 つまたは複数のインデクサーのメンバーを持つ場合の値を指定する必要があります、 element_accessが、インデクサー アクセス (インデクサー アクセス)。Otherwise, the primary_no_array_creation_expression must be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the element_access is an indexer access (Indexer access).

配列へのアクセスArray access

配列アクセスの場合、 primary_no_array_creation_expressionelement_accessの値を指定する必要があります、 array_typeします。For an array access, the primary_no_array_creation_expression of the element_access must be a value of an array_type. さらに、 argument_list配列のアクセスは名前付き引数を格納する許可されません。式の数、 argument_listのランクと同じである必要があります、 array_type、各式は、型にする必要がありますとintuintlongulong、または 1 つ以上のこれらの型に暗黙的に変換する必要があります。Furthermore, the argument_list of an array access is not allowed to contain named arguments.The number of expressions in the argument_list must be the same as the rank of the array_type, and each expression must be of type int, uint, long, ulong, or must be implicitly convertible to one or more of these types.

配列のアクセスの評価結果は、namely で式の値で選択されている配列要素配列の要素型の変数、 argument_listします。The result of evaluating an array access is a variable of the element type of the array, namely the array element selected by the value(s) of the expression(s) in the argument_list.

フォームの配列のアクセスの実行時の処理P[A]ここで、Pは、 primary_no_array_creation_expressionarray_typeAにはargument_list、次の手順で構成されます。The run-time processing of an array access of the form P[A], where P is a primary_no_array_creation_expression of an array_type and A is an argument_list, consists of the following steps:

  • P 評価されます。P is evaluated. この評価は、例外を発生させ、その後の手順は実行されません。If this evaluation causes an exception, no further steps are executed.
  • インデックスの式、 argument_list左から右への順序で評価されます。The index expressions of the argument_list are evaluated in order, from left to right. 次の各インデックスの式の暗黙の変換の評価 (暗黙的な変換)、次の種類のいずれかに実行されます: intuintlongulongします。Following evaluation of each index expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. 暗黙的な変換が存在するこのリストの最初の型が選択されます。The first type in this list for which an implicit conversion exists is chosen. たとえば、型の場合は、インデックスの式shortへの暗黙的な変換しint以降からの暗黙的な変換を実行shortintとの間shortlongが考えられます。For instance, if the index expression is of type short then an implicit conversion to int is performed, since implicit conversions from short to int and from short to long are possible. インデックス式またはそれ以降の暗黙的な変換の評価は、例外を発生させ場合、は、さらにインデックスの式は評価されませんしそれ以上の手順が実行されます。If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed.
  • Pがチェックを有効にします。The value of P is checked to be valid. 場合の値PnullSystem.NullReferenceExceptionがスローされます、以降の手順は実行されません。If the value of P is null, a System.NullReferenceException is thrown and no further steps are executed.
  • 内の各式の値、 argument_listによって参照される配列インスタンスの各次元の実際の境界と照合されますPします。The value of each expression in the argument_list is checked against the actual bounds of each dimension of the array instance referenced by P. 1 つまたは複数の値が範囲外にある場合、System.IndexOutOfRangeExceptionがスローされます、以降の手順は実行されません。If one or more values are out of range, a System.IndexOutOfRangeException is thrown and no further steps are executed.
  • インデックス式で指定された配列要素の位置を計算し、この場所の配列へのアクセスの結果になります。The location of the array element given by the index expression(s) is computed, and this location becomes the result of the array access.

インデクサーへのアクセスIndexer access

インデクサー アクセス用、 primary_no_array_creation_expressionelement_access変数またはクラス、構造体、またはインターフェイスの型の値を指定する必要があり、この型は、1 つまたは複数を実装する必要があります適用できるインデクサー、 argument_listelement_accessします。For an indexer access, the primary_no_array_creation_expression of the element_access must be a variable or value of a class, struct, or interface type, and this type must implement one or more indexers that are applicable with respect to the argument_list of the element_access.

フォームのインデクサー アクセスのバインド時の処理P[A]ここで、Pは、 primary_no_array_creation_expressionクラス、構造体、またはインターフェイス型のT、およびAが、argument_list、次の手順で構成されます。The binding-time processing of an indexer access of the form P[A], where P is a primary_no_array_creation_expression of a class, struct, or interface type T, and A is an argument_list, consists of the following steps:

  • 一連のインデクサーによって提供されるTを構築します。The set of indexers provided by T is constructed. 宣言されているすべてのインデクサーはセットTの基本型またはTれていないoverride宣言とは、現在のコンテキストでアクセスできるように (メンバー アクセス)。The set consists of all indexers declared in T or a base type of T that are not override declarations and are accessible in the current context (Member access).
  • セットは、その他のインデクサーによって隠ぺいされていない適用可能なインデクサーだけに縮小されます。The set is reduced to those indexers that are applicable and not hidden by other indexers. 次の規則は、各インデクサーに適用されますS.I、セット内でSの種類は、インデクサーIは宣言されています。The following rules are applied to each indexer S.I in the set, where S is the type in which the indexer I is declared:
    • 場合Iを適用可能でないA(適用可能な関数メンバー)、しIセットから削除されます。If I is not applicable with respect to A (Applicable function member), then I is removed from the set.
    • 場合Iを適用できるA(適用可能な関数メンバー) の基本型ですべてのインデクサーを宣言し、Sセットから削除されます。If I is applicable with respect to A (Applicable function member), then all indexers declared in a base type of S are removed from the set.
    • 場合Iを適用できるA(適用可能な関数メンバー) とSクラス型は他にも、objectインターフェイスで宣言されているすべてのインデクサーは、セットから削除されます。If I is applicable with respect to A (Applicable function member) and S is a class type other than object, all indexers declared in an interface are removed from the set.
  • インデクサーの候補の結果セットが空の場合、該当するインデクサーが存在していないため、し、バインド エラーが発生します。If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs.
  • オーバー ロード解決規則を使用して、一連の候補のインデクサーの最適なインデクサーが識別されるオーバー ロードの解決します。The best indexer of the set of candidate indexers is identified using the overload resolution rules of Overload resolution. 1 つの最適なインデクサーを識別できない場合、インデクサー アクセスはあいまいであり、バインド エラーが発生します。If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs.
  • インデックスの式、 argument_list左から右への順序で評価されます。The index expressions of the argument_list are evaluated in order, from left to right. インデクサーのアクセスの処理の結果は、インデクサー アクセスとして分類される式です。The result of processing the indexer access is an expression classified as an indexer access. インデクサー アクセス式は、上記の手順で決定されたインデクサーが参照し、の関連付けられたインスタンス式がありますPと関連付けられている引数リストのAします。The indexer access expression references the indexer determined in the step above, and has an associated instance expression of P and an associated argument list of A.

インデクサー アクセスのいずれかの呼び出しの原因が使用されるコンテキストに応じて、 get アクセサーまたはset アクセサーのインデクサー。Depending on the context in which it is used, an indexer access causes invocation of either the get accessor or the set accessor of the indexer. インデクサーへのアクセスが、割り当ての対象である場合、 set アクセサー新しい値を割り当てるために呼び出される (単純な代入)。If the indexer access is the target of an assignment, the set accessor is invoked to assign a new value (Simple assignment). その他のすべてのケースで、 get アクセサー 、現在の値を取得するために呼び出す (式の値)。In all other cases, the get accessor is invoked to obtain the current value (Values of expressions).

このアクセスThis access

A this_access予約語から成るthisします。A this_access consists of the reserved word this.

this_access
    : 'this'
    ;

A this_accessでのみ許可されている、ブロックのインスタンス コンス トラクター、インスタンス メソッドまたはインスタンス アクセサー。A this_access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. 意味は次のいずれかがあります。It has one of the following meanings:

  • ときにthisで使用されて、 primary_expressionクラスのインスタンス コンス トラクター、内の値として分類されます。When this is used in a primary_expression within an instance constructor of a class, it is classified as a value. 値の型は、インスタンスの型 (インスタンス型) で、使用状況が発生した、値が構築されるオブジェクトへの参照をクラスの。The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object being constructed.
  • ときにthisで使用されて、 primary_expression値として、インスタンス メソッドまたはクラスのインスタンスのアクセサー内で分類されます。When this is used in a primary_expression within an instance method or instance accessor of a class, it is classified as a value. 値の型は、インスタンスの型 (インスタンス型) で、使用状況が発生した、値がメソッドまたはアクセサーが呼び出されたオブジェクトへの参照をクラスの。The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object for which the method or accessor was invoked.
  • ときにthisで使用されて、 primary_expression構造体のインスタンス コンス トラクター内で変数として分類されます。When this is used in a primary_expression within an instance constructor of a struct, it is classified as a variable. 変数の型は、インスタンスの型 (インスタンス型) の構造体で、使用状況が発生した、変数が作成される構造体を表します。The type of the variable is the instance type (The instance type) of the struct within which the usage occurs, and the variable represents the struct being constructed. this構造体のインスタンス コンス トラクターの変数はまったく同じように動作するout構造体の型のパラメーター-具体的には、つまり、変数を間違いなく、インスタンスのすべての実行パスで割り当てる必要がありますコンス トラクターです。The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor.
  • ときにthisで使用されて、 primary_expression内で、インスタンス メソッドまたはインスタンス アクセサー構造体の変数として分類されます。When this is used in a primary_expression within an instance method or instance accessor of a struct, it is classified as a variable. 変数の型は、インスタンスの型 (インスタンス型) 使用する構造体の。The type of the variable is the instance type (The instance type) of the struct within which the usage occurs.
    • メソッドまたはアクセサーは、反復子ではない場合 (反復子)、this変数は、対象の構造体、メソッドまたはアクセサーが呼び出されたとまったく同じ動作を表します、ref構造体の型のパラメーター。If the method or accessor is not an iterator (Iterators), the this variable represents the struct for which the method or accessor was invoked, and behaves exactly the same as a ref parameter of the struct type.
    • メソッドまたはアクセサーが、反復子の場合、this変数は、対象のメソッドまたはアクセサーが呼び出され、構造体の型の値を持つパラメーターとまったく同じ動作には、構造体のコピーを表します。If the method or accessor is an iterator, the this variable represents a copy of the struct for which the method or accessor was invoked, and behaves exactly the same as a value parameter of the struct type.

使用thisで、 primary_expression上に挙げた以外のコンテキストでは、コンパイル時エラー。Use of this in a primary_expression in a context other than the ones listed above is a compile-time error. 具体的を参照することはできませんthisまたは静的プロパティのアクセサーでは、静的メソッドで、 variable_initializerフィールド宣言のです。In particular, it is not possible to refer to this in a static method, a static property accessor, or in a variable_initializer of a field declaration.

基本アクセスBase access

A base_accessの予約語で構成されますbaseか後に、"."トークン識別子や、 argument_list角かっこで囲まれています。A base_access consists of the reserved word base followed by either a "." token and an identifier or an argument_list enclosed in square brackets:

base_access
    : 'base' '.' identifier
    | 'base' '[' expression_list ']'
    ;

A base_access現在のクラスまたは構造体で同じ名前のメンバーでは非表示の基本クラス メンバーにアクセスするために使用します。A base_access is used to access base class members that are hidden by similarly named members in the current class or struct. A base_accessでのみ許可されている、ブロックのインスタンス コンス トラクター、インスタンス メソッドまたはインスタンス アクセサー。A base_access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. ときにbase.Iクラスまたは構造体で発生したIそのクラスまたは構造体の基本クラスのメンバーを表す必要があります。When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct. 同様に、base[E]を適用できるインデクサーは、基底クラスに存在する必要があります、クラス内に発生します。Likewise, when base[E] occurs in a class, an applicable indexer must exist in the base class.

バインディング時に、 base_access形式の式base.Ibase[E]書き込まれている場合と同じように評価されます((B)this).I((B)this)[E]ここで、Bクラスの基本クラスですまたは、構造体、構造に発生します。At binding-time, base_access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. したがって、base.Ibase[E]に対応this.Ithis[E]、除くthis基底クラスのインスタンスとして表示されています。Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.

ときに、 base_accessうち決定関数の実行時に呼び出すメンバー仮想関数メンバー (メソッド、プロパティ、またはインデクサー) を参照して (コンパイル時の動的なオーバー ロードの解決の確認) が変更されました。When a base_access references a virtual function member (a method, property, or indexer), the determination of which function member to invoke at run-time (Compile-time checking of dynamic overload resolution) is changed. 呼び出される関数メンバーは、最派生実装を見つけることによって決まります (仮想メソッド) を関数メンバーのB(の代わりの実行時の型に関してthis、としてなりますベース以外のアクセスに通常)。The function member that is invoked is determined by finding the most derived implementation (Virtual methods) of the function member with respect to B (instead of with respect to the run-time type of this, as would be usual in a non-base access). 内でそのため、overridevirtual関数のメンバー、 base_access関数メンバーの継承された実装を呼び出すために使用できます。Thus, within an override of a virtual function member, a base_access can be used to invoke the inherited implementation of the function member. によって参照される関数のメンバーである場合、 base_accessは抽象でバインド エラーが発生します。If the function member referenced by a base_access is abstract, a binding-time error occurs.

後置インクリメント演算子と後置デクリメント演算子Postfix increment and decrement operators

post_increment_expression
    : primary_expression '++'
    ;

post_decrement_expression
    : primary_expression '--'
    ;

オペランドの後置インクリメントまたはデクリメント操作は、変数、プロパティ アクセス、またはインデクサー アクセスとして分類される式をする必要があります。The operand of a postfix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. 操作の結果は、オペランドと同じ型の値です。The result of the operation is a value of the same type as the operand.

場合、 primary_expressionコンパイル時の型を持つdynamic演算子が動的にバインドし、(動的バインド)、 post_increment_expressionまたはpost_decrement_expressionコンパイル時の型を持つdynamicの実行時の型を使用して実行時に次の規則を適用し、 primary_expressionします。If the primary_expression has the compile-time type dynamic then the operator is dynamically bound (Dynamic binding), the post_increment_expression or post_decrement_expression has the compile-time type dynamic and the following rules are applied at run-time using the run-time type of the primary_expression.

場合は、オペランドを後置のインクリメントまたはデクリメント演算は、プロパティまたはインデクサー アクセス、プロパティまたはインデクサーが両方必要、getsetアクセサー。If the operand of a postfix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. サポートしていない場合は、バインド時エラーが発生します。If this is not the case, a binding-time error occurs.

単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。Unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. 定義済みの++--演算子は、次の種類の存在: sbytebyteshortushortintuintlongulongcharfloatdoubledecimal、および任意の列挙型。Predefined ++ and -- operators exist for the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, and any enum type. 定義済み++演算子がオペランドを定義済みに 1 を追加することによって生成された値を返す--演算子オペランドから 1 を引いた値を返します。The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined -- operators return the value produced by subtracting 1 from the operand. checked場合この加算または減算の結果が結果の型の範囲外と結果型が整数型または列挙型では、コンテキスト、System.OverflowExceptionがスローされます。In a checked context, if the result of this addition or subtraction is outside the range of the result type and the result type is an integral type or enum type, a System.OverflowException is thrown.

実行時の処理の後置インクリメントまたはデクリメント演算子は、フォームのx++またはx--次の手順で構成されています。The run-time processing of a postfix increment or decrement operation of the form x++ or x-- consists of the following steps:

  • 場合x変数として分類されます。If x is classified as a variable:
    • x 変数を生成するために評価されます。x is evaluated to produce the variable.
    • x保存されます。The value of x is saved.
    • 選択した演算子が呼び出されるの保存された値とx引数として。The selected operator is invoked with the saved value of x as its argument.
    • 評価によって指定した位置に、演算子によって返される値が格納されているxします。The value returned by the operator is stored in the location given by the evaluation of x.
    • 保存された値x操作の結果になります。The saved value of x becomes the result of the operation.
  • 場合xプロパティまたはインデクサーのアクセスに分類されます。If x is classified as a property or indexer access:
    • インスタンス式 (場合xないstatic) および引数リスト (場合xインデクサー アクセス) に関連付けられているxが評価されると、その後で、結果の使用getsetアクセサーの呼び出し。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
    • getのアクセサーxが呼び出される、返される値を保存します。The get accessor of x is invoked and the returned value is saved.
    • 選択した演算子が呼び出されるの保存された値とx引数として。The selected operator is invoked with the saved value of x as its argument.
    • setのアクセサーxが呼び出されると演算子によって返される値とそのvalue引数。The set accessor of x is invoked with the value returned by the operator as its value argument.
    • 保存された値x操作の結果になります。The saved value of x becomes the result of the operation.

++--演算子もサポートしてプレフィックス表記 (前置インクリメントとデクリメント演算子)。The ++ and -- operators also support prefix notation (Prefix increment and decrement operators). 結果では通常、x++またはx--の値は、x操作の前に一方の結果++xまたは--xの値は、x操作の完了後します。Typically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. いずれの場合も、x自体、操作の後に同じ値に含まれています。In either case, x itself has the same value after the operation.

operator ++またはoperator --実装は、いずれかの後置または前置表記を使用して呼び出すことができます。An operator ++ or operator -- implementation can be invoked using either postfix or prefix notation. 2 つの表記の個別の演算子の実装を持つことはできません。It is not possible to have separate operator implementations for the two notations.

新しい演算子The new operator

new演算子を使用して、型の新しいインスタンスを作成します。The new operator is used to create new instances of types.

3 つの形式があるnew式。There are three forms of new expressions:

  • オブジェクト作成式は、クラス型と値の型の新しいインスタンスを作成に使用されます。Object creation expressions are used to create new instances of class types and value types.
  • 配列作成式は、配列型の新しいインスタンスを作成に使用されます。Array creation expressions are used to create new instances of array types.
  • 型のデリゲートの新しいインスタンスを作成するデリゲート作成式が使用されます。Delegate creation expressions are used to create new instances of delegate types.

new演算子は、型のインスタンスの作成を意味しますが、メモリの動的な割り当てを必ずしも意味しません。The new operator implies creation of an instance of a type, but does not necessarily imply dynamic allocation of memory. 具体的には、値型のインスタンスには存在して、動的な割り当ては発生しませんが、変数を超える追加のメモリ必要ないときnew値型のインスタンスを作成するために使用します。In particular, instances of value types require no additional memory beyond the variables in which they reside, and no dynamic allocations occur when new is used to create instances of value types.

オブジェクト作成式Object creation expressions

Object_creation_expressionの新しいインスタンスを作成するために使用するclass_typeまたはvalue_typeします。An object_creation_expression is used to create a new instance of a class_type or a value_type.

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

object_or_collection_initializer
    : object_initializer
    | collection_initializer
    ;

object_creation_expression必要があります、 class_typevalue_typeまたはtype_parameter.The type of an object_creation_expression must be a class_type, a value_type or a type_parameter. することはできません、 abstract class_typeします。The type cannot be an abstract class_type.

省略可能なargument_list (引数リスト) 場合にのみが許可されている、は、 class_typeまたはstruct_型します。The optional argument_list (Argument lists) is permitted only if the type is a class_type or a struct_type.

オブジェクト作成式でコンス トラクターの引数リストを省略でき、外側のかっこ、オブジェクト初期化子またはコレクション初期化子が含まれています。An object creation expression can omit the constructor argument list and enclosing parentheses provided it includes an object initializer or collection initializer. コンス トラクターの引数リストを省略して、外側のかっこは、空の引数リストを指定することと同じです。Omitting the constructor argument list and enclosing parentheses is equivalent to specifying an empty argument list.

オブジェクト初期化子またはコレクション初期化子を含むオブジェクト作成式の処理は、最初にインスタンス コンス トラクターを処理し、オブジェクト初期化子 (で指定されたメンバーまたは要素の初期化を処理し、オブジェクト初期化子) またはコレクション初期化子 (コレクション初期化子)。Processing of an object creation expression that includes an object initializer or collection initializer consists of first processing the instance constructor and then processing the member or element initializations specified by the object initializer (Object initializers) or collection initializer (Collection initializers).

場合、省略可能な引数のいずれかargument_listコンパイル時の型を持つdynamicobject_creation_expressionが動的にバインドされている (の動的バインド)これらの引数の実行時の型を使用して実行時に次の規則を適用し、 argument_listコンパイル時の型があるdynamicします。If any of the arguments in the optional argument_list has the compile-time type dynamic then the object_creation_expression is dynamically bound (Dynamic binding) and the following rules are applied at run-time using the run-time type of those arguments of the argument_list that have the compile time type dynamic. オブジェクトの作成に限定のコンパイル時のチェックが行われます」の説明に従って、コンパイル時の動的なオーバー ロードの解決チェックします。However, the object creation undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

バインド時の処理、 object_creation_expressionフォームのnew T(A)ここで、Tは、 class_typeまたはvalue_typeAは省略可能なargument_list、次の手順で構成されます。The binding-time processing of an object_creation_expression of the form new T(A), where T is a class_type or a value_type and A is an optional argument_list, consists of the following steps:

  • 場合Tは、 value_typeAが存在しません。If T is a value_type and A is not present:
    • Object_creation_expressionは既定のコンス トラクターの呼び出し。The object_creation_expression is a default constructor invocation. 結果、 object_creation_expression型の値は、Tの既定値 namelyTで定義されている、System.ValueType 型します。The result of the object_creation_expression is a value of type T, namely the default value for T as defined in The System.ValueType type.
  • の場合Tは、 type_parameterAが存在しません。Otherwise, if T is a type_parameter and A is not present:
    • 値型の制約またはコンス トラクター制約のない場合 (入力パラメーターの制約) が指定されているT、バインド エラーが発生します。If no value type constraint or constructor constraint (Type parameter constraints) has been specified for T, a binding-time error occurs.
    • 結果、 object_creation_expression型パラメーターのバインドが、実行時型の値は、その型の既定のコンス トラクターの呼び出しの namely の結果。The result of the object_creation_expression is a value of the run-time type that the type parameter has been bound to, namely the result of invoking the default constructor of that type. 実行時の型には、参照型または値型があります。The run-time type may be a reference type or a value type.
  • の場合Tは、 class_typeまたはstruct_type:Otherwise, if T is a class_type or a struct_type:
    • 場合Tは、 abstract class_typeコンパイル時エラーが発生します。If T is an abstract class_type, a compile-time error occurs.
    • インスタンス コンス トラクターを呼び出すには、オーバー ロード解決規則を使用して決定されますオーバー ロードの解決します。The instance constructor to invoke is determined using the overload resolution rules of Overload resolution. インスタンス コンス トラクターの候補のセットの構成で宣言されているすべてのアクセス可能なインスタンス コンス トラクターがTに関して適用されるA(適用可能な関数メンバー)。The set of candidate instance constructors consists of all accessible instance constructors declared in T which are applicable with respect to A (Applicable function member). インスタンス コンス トラクターの候補のセットが空の場合、または 1 つの最適なインスタンス コンス トラクターを識別できない場合は、バインド時のエラーが発生します。If the set of candidate instance constructors is empty, or if a single best instance constructor cannot be identified, a binding-time error occurs.
    • 結果、 object_creation_expression型の値は、 T、つまり前の手順で決定されたインスタンス コンス トラクターを呼び出すことによって生成される値。The result of the object_creation_expression is a value of type T, namely the value produced by invoking the instance constructor determined in the step above.
  • それ以外の場合、 object_creation_expressionが有効でないバインド時のエラーが発生したとします。Otherwise, the object_creation_expression is invalid, and a binding-time error occurs.

場合でも、 object_creation_expressionは動的にバインドすると、コンパイル時の型がまだTします。Even if the object_creation_expression is dynamically bound, the compile-time type is still T.

実行時の処理、 object_creation_expressionフォームのnew T(A)ここで、Tclass_typeまたはstruct_typeAは省略可能なargument_list、次の手順で構成されます。The run-time processing of an object_creation_expression of the form new T(A), where T is class_type or a struct_type and A is an optional argument_list, consists of the following steps:

  • 場合Tは、 class_type:If T is a class_type:
    • クラスの新しいインスタンスTが割り当てられます。A new instance of class T is allocated. 新しいインスタンスを割り当てることができる十分なメモリがない場合、System.OutOfMemoryExceptionがスローされます、以降の手順は実行されません。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
    • 新しいインスタンスのすべてのフィールドが既定値に初期化されます (既定値)。All fields of the new instance are initialized to their default values (Default values).
    • 関数メンバーの呼び出しの規則に従って、インスタンス コンス トラクターが呼び出されます (コンパイル時の動的なオーバー ロードの解決チェック)。The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). 新しく割り当てられたインスタンスへの参照が自動的にインスタンス コンス トラクターに渡されます、としてコンス トラクターの中から、インスタンスにアクセスできるthisします。A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.
  • 場合Tは、 struct_type:If T is a struct_type:
    • 型のインスタンスTは一時ローカル変数を割り当てることによって作成されます。An instance of type T is created by allocating a temporary local variable. 以降のインスタンス コンス トラクター、 struct_type一時変数の初期化する必要はありませんが、作成中のインスタンスの各フィールドに値を確実に代入するが必要です。Since an instance constructor of a struct_type is required to definitely assign a value to each field of the instance being created, no initialization of the temporary variable is necessary.
    • 関数メンバーの呼び出しの規則に従って、インスタンス コンス トラクターが呼び出されます (コンパイル時の動的なオーバー ロードの解決チェック)。The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). 新しく割り当てられたインスタンスへの参照が自動的にインスタンス コンス トラクターに渡されます、としてコンス トラクターの中から、インスタンスにアクセスできるthisします。A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.

オブジェクト初期化子Object initializers

オブジェクト初期化子フィールド、プロパティまたはオブジェクトのインデックス付きの要素の 0 個以上の値を指定します。An object initializer specifies values for zero or more fields, properties or indexed elements of an object.

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

member_initializer_list
    : member_initializer (',' member_initializer)*
    ;

member_initializer
    : initializer_target '=' initializer_value
    ;

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

initializer_value
    : expression
    | object_or_collection_initializer
    ;

オブジェクト初期化子で囲まれた、メンバー初期化子のシーケンスから成る{}トークンし、コンマで区切られました。An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas. member_initializer初期化するためのターゲットを指定します。Each member_initializer designates a target for the initialization. 識別子一方、アクセス可能なフィールドまたはプロパティが初期化されているオブジェクトの名前、 argument_listで囲む角かっこでアクセス可能なインデクサーの引数を指定する必要があります、初期化されるオブジェクト。An identifier must name an accessible field or property of the object being initialized, whereas an argument_list enclosed in square brackets must specify arguments for an accessible indexer on the object being initialized. オブジェクト初期化子を同じフィールドまたはプロパティの 1 つ以上のメンバー初期化子を含めるとエラーになります。It is an error for an object initializer to include more than one member initializer for the same field or property.

initializer_target等号と式、オブジェクト初期化子またはコレクション初期化子を続けています。Each initializer_target is followed by an equals sign and either an expression, an object initializer or a collection initializer. 新しく作成されたオブジェクトが初期化を参照するオブジェクト初期化子内の式のことはできません。It is not possible for expressions within the object initializer to refer to the newly created object it is initializing.

割り当てと同じ方法で、等号が処理された後に式を指定するメンバーの初期化子 (単純な代入) をターゲットにします。A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment (Simple assignment) to the target.

等号の後に、オブジェクト初期化子を指定するメンバーの初期化子、入れ子になったオブジェクトの初期化子、つまり、埋め込みオブジェクトの初期化。A member initializer that specifies an object initializer after the equals sign is a nested object initializer, i.e. an initialization of an embedded object. フィールドまたはプロパティに新しい値を割り当てる代わりに、入れ子になったオブジェクト初期化子の割り当ては、フィールドまたはプロパティのメンバーへの割り当てとして扱われます。Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. 入れ子になったオブジェクト初期化子は、値の型を持つプロパティ、または値型を持つ読み取り専用のフィールドに適用できません。Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type.

等号の後に、コレクション初期化子を指定するメンバーの初期化子は、コレクションが埋め込まれたの初期化です。A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. 新しいコレクションを対象のフィールド、プロパティまたはインデクサーに割り当てる代わりに、初期化子で指定された要素は、ターゲットによって参照されるコレクションに追加されます。Instead of assigning a new collection to the target field, property or indexer, the elements given in the initializer are added to the collection referenced by the target. コレクション型で指定された要件を満たす必要がありますの対象にコレクション初期化子します。The target must be of a collection type that satisfies the requirements specified in Collection initializers.

インデックス初期化子の引数は、1 回だけ常に評価されます。The arguments to an index initializer will always be evaluated exactly once. したがって、引数は、(例: 空の入れ子になった初期化子) により使用される作業終了、場合でもは、副作用が評価されます。Thus, even if the arguments end up never getting used (e.g. because of an empty nested initializer), they will be evaluated for their side effects.

次のクラスは、2 つの座標の点を表します。The following class represents a point with two coordinates:

public class Point
{
    int x, y;

    public int X { get { return x; } set { x = value; } }
    public int Y { get { return y; } set { y = value; } }
}

インスタンスPoint作成および初期化を次のようにできます。An instance of Point can be created and initialized as follows:

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

同じ効果があります。which has the same effect as

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

場所__a一時変数で、それ以外の場合に非表示とアクセスできません。where __a is an otherwise invisible and inaccessible temporary variable. 次のクラスは、2 つの点から作成された四角形を表します。The following class represents a rectangle created from two points:

public class Rectangle
{
    Point p1, p2;

    public Point P1 { get { return p1; } set { p1 = value; } }
    public Point P2 { get { return p2; } set { p2 = value; } }
}

インスタンスRectangle作成および初期化を次のようにできます。An instance of Rectangle can be created and initialized as follows:

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

同じ効果があります。which has the same effect as

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一時変数アクセス、それ以外の場合です。where __r, __p1 and __p2 are temporary variables that are otherwise invisible and inaccessible.

場合Rectangleのコンス トラクターでは、2 つが埋め込まれたPointインスタンスIf Rectangle's constructor allocates the two embedded Point instances

public class Rectangle
{
    Point p1 = new Point();
    Point p2 = new Point();

    public Point P1 { get { return p1; } }
    public Point P2 { get { return p2; } }
}

次の構成体は、埋め込みの初期化に使用できるPointの新しいインスタンスを割り当てる代わりにインスタンス。the following construct can be used to initialize the embedded Point instances instead of assigning new instances:

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

同じ効果があります。which has the same effect as

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

C では、次の例では、の適切な定義を指定します。Given an appropriate definition of C, the following example:

var c = new C {
    x = true,
    y = { a = "Hello" },
    z = { 1, 2, 3 },
    ["x"] = 5,
    [0,0] = { "a", "b" },
    [1,2] = {}
};

この一連の割り当てと同等です。is equivalent to this series of assignments:

C __c = new C();
__c.x = true;
__c.y.a = "Hello";
__c.z.Add(1); 
__c.z.Add(2);
__c.z.Add(3);
string __i1 = "x";
__c[__i1] = 5;
int __i2 = 0, __i3 = 0;
__c[__i2,__i3].Add("a");
__c[__i2,__i3].Add("b");
int __i4 = 1, __i5 = 2;
var c = __c;

場所__cなど、生成された変数は非表示と、ソース コードにアクセスできないです。where __c, etc., are generated variables that are invisible and inaccessible to the source code. なお、引数の[0,0]は 1 回だけ評価、および引数を[1,2]使用されない場合でも、1 回評価されます。Note that the arguments for [0,0] are evaluated only once, and the arguments for [1,2] are evaluated once even though they are never used.

コレクション初期化子Collection initializers

コレクション初期化子では、コレクションの要素を指定します。A collection initializer specifies the elements of a collection.

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)*
    ;

コレクション初期化子で囲まれた、要素の初期化子のシーケンスから成る{}トークンし、コンマで区切られました。A collection initializer consists of a sequence of element initializers, enclosed by { and } tokens and separated by commas. 各要素の初期化子の初期化中にコレクション オブジェクトに追加する要素を指定およびで囲まれた式の一覧から成る{}トークンし、コンマで区切られました。Each element initializer specifies an element to be added to the collection object being initialized, and consists of a list of expressions enclosed by { and } tokens and separated by commas. 1 つの式の要素の初期化子は、中かっこなしで記述できますが、メンバー初期化子とあいまいさを避けるために、代入式にすることはできませんし。A single-expression element initializer can be written without braces, but cannot then be an assignment expression, to avoid ambiguity with member initializers. Non_assignment_expressionで定義されている運用します。The non_assignment_expression production is defined in Expression.

コレクション初期化子を含むオブジェクト作成式の例を次に示します。The following is an example of an object creation expression that includes a collection initializer:

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

実装する型のコレクション オブジェクトをコレクション初期化子を適用する必要がありますSystem.Collections.IEnumerableコンパイル時エラーが発生します。The collection object to which a collection initializer is applied must be of a type that implements System.Collections.IEnumerable or a compile-time error occurs. コレクション初期化子を呼び出す順序で要素を指定された各、Addターゲット上のメソッドは、引数のリストを使用して、通常のメンバーの参照を適用する要素初期化子の式のリストを持つオブジェクトし、オーバー ロードの呼び出しごとの解決。For each specified element in order, the collection initializer invokes an Add method on the target object with the expression list of the element initializer as argument list, applying normal member lookup and overload resolution for each invocation. そのため、コレクション オブジェクトが、名前の該当するインスタンスまたは拡張メソッドをいる必要がありますAddの各要素の初期化子。Thus, the collection object must have an applicable instance or extension method with the name Add for each element initializer.

次のクラスは、名前と電話番号のリストで連絡先を表します。The following class represents a contact with a name and a list of phone numbers:

public class Contact
{
    string name;
    List<string> phoneNumbers = new List<string>();

    public string Name { get { return name; } set { name = value; } }

    public List<string> PhoneNumbers { get { return phoneNumbers; } }
}

AList<Contact>作成および初期化を次のようにできます。A List<Contact> can be created and initialized as follows:

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" }
    }
};

同じ効果があります。which has the same effect as

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一時変数アクセス、それ以外の場合です。where __clist, __c1 and __c2 are temporary variables that are otherwise invisible and inaccessible.

配列作成式Array creation expressions

Array_creation_expressionの新しいインスタンスを作成するために使用するarray_typeします。An array_creation_expression is used to create a new instance of an 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
    ;

最初の形式の配列作成式では、それぞれの個別の式を式の一覧から削除した結果の型の配列インスタンスを割り当てます。An array creation expression of the first form allocates an array instance of the type that results from deleting each of the individual expressions from the expression list. 配列作成式ではたとえば、new int[10,20]型の配列インスタンスの生成int[,]と、配列作成式new int[10][,]型の配列が生成されるint[][,]For example, the array creation expression new int[10,20] produces an array instance of type int[,], and the array creation expression new int[10][,] produces an array of type int[][,]. 式のリスト内の各式は型でなければなりませんintuintlong、またはulong、または 1 つ以上のこれらの型に暗黙的に変換します。Each expression in the expression list must be of type int, uint, long, or ulong, or implicitly convertible to one or more of these types. 各式の値は、新しく割り当てられた配列のインスタンスに対応する次元の長さを決定します。The value of each expression determines the length of the corresponding dimension in the newly allocated array instance. コンパイル時エラーには、配列の次元の長さは 0 以上である必要があります、ため、 constant_expression負の値式の一覧。Since the length of an array dimension must be nonnegative, it is a compile-time error to have a constant_expression with a negative value in the expression list.

Unsafe コンテキストでは可 (Unsafe コンテキスト)、配列のレイアウトは指定されていません。Except in an unsafe context (Unsafe contexts), the layout of arrays is unspecified.

配列作成式最初のフォームにはには、配列初期化子が含まれている場合は、式のリスト内の各式は定数である必要があり、配列初期化子の式のリストで指定されたランクと次元の長さが一致する必要があります。If an array creation expression of the first form includes an array initializer, each expression in the expression list must be a constant and the rank and dimension lengths specified by the expression list must match those of the array initializer.

2 番目または 3 番目のフォームの配列作成式で配列初期化子を指定した配列の型、ランク付けの指定子のランクが一致する必要があります。In an array creation expression of the second or third form, the rank of the specified array type or rank specifier must match that of the array initializer. 各次元の長さは、配列初期化子の対応する入れ子のレベルの各要素の数から推論されます。The individual dimension lengths are inferred from the number of elements in each of the corresponding nesting levels of the array initializer. したがって、式Thus, the expression

new int[,] {{0, 1}, {2, 3}, {4, 5}}

正確に対応していますexactly corresponds to

new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}

3 番目の形式の配列作成式として参照されます、配列作成式を暗黙的に型指定されたします。An array creation expression of the third form is referred to as an implicitly typed array creation expression. 配列の要素の型が明示的に指定されていないが、最も一般的な種類として決定する点を除いて、2 番目の形式に似ています (一連の式の最適な一般的な種類を検索する) の配列内の式のセット初期化子。It is similar to the second form, except that the element type of the array is not explicitly given, but determined as the best common type (Finding the best common type of a set of expressions) of the set of expressions in the array initializer. 、多次元配列の 1 つの場所など、 rank_specifierに少なくとも 1 つのコンマを含んでいますこのセットはすべてで構成されますs がで検出された入れ子になったarray_initializer秒。For a multidimensional array, i.e., one where the rank_specifier contains at least one comma, this set comprises all expressions found in nested array_initializers.

配列初期化子の詳細については配列初期化子します。Array initializers are described further in Array initializers.

配列作成式の評価結果は、新しく割り当てられた配列インスタンスへの参照を namely の値として分類されます。The result of evaluating an array creation expression is classified as a value, namely a reference to the newly allocated array instance. 配列作成式の実行時の処理は、次の手順で構成されます。The run-time processing of an array creation expression consists of the following steps:

  • ディメンションの長さの式、 expression_list左から右への順序で評価されます。The dimension length expressions of the expression_list are evaluated in order, from left to right. 暗黙的な変換をそれぞれの式の評価に従って (暗黙的な変換)、次の種類のいずれかに実行されます: intuintlongulongします。Following evaluation of each expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. 暗黙的な変換が存在するこのリストの最初の型が選択されます。The first type in this list for which an implicit conversion exists is chosen. 式またはそれ以降の暗黙的な変換の評価は、例外を発生させ場合、は、それ以上の式は評価されませんしさらに手順は実行されません。If evaluation of an expression or the subsequent implicit conversion causes an exception, then no further expressions are evaluated and no further steps are executed.
  • 次元の長さの計算値は、次のように検証されます。The computed values for the dimension lengths are validated as follows. 1 つ以上の値は 0 より小さい場合、System.OverflowExceptionがスローされます、以降の手順は実行されません。If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.
  • 指定した次元の長さを持つ配列インスタンスが割り当てられます。An array instance with the given dimension lengths is allocated. 新しいインスタンスを割り当てることができる十分なメモリがない場合、System.OutOfMemoryExceptionがスローされます、以降の手順は実行されません。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
  • 新しい配列インスタンスのすべての要素は、既定値に初期化されます (既定値)。All elements of the new array instance are initialized to their default values (Default values).
  • 配列作成式に配列初期化子が含まれている場合、配列初期化子内の各式が評価され、配列の対応する要素に割り当てられています。If the array creation expression contains an array initializer, then each expression in the array initializer is evaluated and assigned to its corresponding array element. 評価と割り当てが、式が配列初期化子で記述された順序で実行、つまり、要素が昇順に最初に増やすと、右端の次元でインデックス順に初期化されます。The evaluations and assignments are performed in the order the expressions are written in the array initializer—in other words, elements are initialized in increasing index order, with the rightmost dimension increasing first. 指定された式または対応する配列要素への割り当てを後続の評価は、例外を発生させ場合、残りの要素が初期化されていません (し、残りの要素が既定値がそのため)。If evaluation of a given expression or the subsequent assignment to the corresponding array element causes an exception, then no further elements are initialized (and the remaining elements will thus have their default values).

配列作成式が配列型の要素の配列をインスタンス化を許可しますが、このような配列の要素を手動で初期化する必要があります。An array creation expression permits instantiation of an array with elements of an array type, but the elements of such an array must be manually initialized. たとえば、ステートメントFor example, the statement

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

型の 100 個の要素を持つ 1 次元配列を作成int[]です。creates a single-dimensional array with 100 elements of type int[]. 各要素の初期値はnullします。The initial value of each element is null. サブ配列、およびステートメントのインスタンス化も同じ配列作成式のことはできません。It is not possible for the same array creation expression to also instantiate the sub-arrays, and the statement

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

コンパイル時エラーが発生します。results in a compile-time error. サブ配列のインスタンス化は、手動で代わりに実行する必要があります。Instantiation of the sub-arrays must instead be performed manually, as in

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

配列の配列に、サブ配列は、すべて同じ長さの場合は、「四角形」図形がある場合は、多次元配列を使用する方が効率的です。When an array of arrays has a "rectangular" shape, that is when the sub-arrays are all of the same length, it is more efficient to use a multi-dimensional array. 上記の例では、配列の配列のインスタンス化が 101 個のオブジェクトを作成します。-外側の配列が 1 つと 100 のサブ配列。In the example above, instantiation of the array of arrays creates 101 objects—one outer array and 100 sub-arrays. それに対してIn contrast,

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

のみ、1 つのオブジェクト、2 次元の配列を作成し、単一のステートメントで割り当てを行うこと。creates only a single object, a two-dimensional array, and accomplishes the allocation in a single statement.

暗黙的に型指定された配列作成式の例を次に示します。The following are examples of implicitly typed array creation expressions:

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

最後の式がコンパイル時エラーを発生もintstring、他の暗黙的に変換できるし、入力はない最も一般的な存在です。The last expression causes a compile-time error because neither int nor string is implicitly convertible to the other, and so there is no best common type. 明示的に型指定された配列作成式に必要ここでは、たとえば、型を指定するobject[]します。An explicitly typed array creation expression must be used in this case, for example specifying the type to be object[]. または、要素のいずれかに共通の基本型が推論される要素の型になりますし、キャストできます。Alternatively, one of the elements can be cast to a common base type, which would then become the inferred element type.

暗黙的に型指定された配列作成式は、匿名オブジェクト初期化子と組み合わせることができます (匿名オブジェクト作成式) 匿名で作成するデータ構造を入力します。Implicitly typed array creation expressions can be combined with anonymous object initializers (Anonymous object creation expressions) to create anonymously typed data structures. 例:For example:

var contacts = new[] {
    new {
        Name = "Chris Smith",
        PhoneNumbers = new[] { "206-555-0101", "425-882-8080" }
    },
    new {
        Name = "Bob Harris",
        PhoneNumbers = new[] { "650-555-0199" }
    }
};

デリゲート作成式Delegate creation expressions

A delegate_creation_expressionの新しいインスタンスを作成するために使用するdelegate_typeします。A delegate_creation_expression is used to create a new instance of a delegate_type.

delegate_creation_expression
    : 'new' delegate_type '(' expression ')'
    ;

デリゲート作成式の引数が、メソッド グループ、匿名関数またはコンパイル時の型の値にする必要がありますdynamicまたはdelegate_typeします。The argument of a delegate creation expression must be a method group, an anonymous function or a value of either the compile time type dynamic or a delegate_type. 引数が、メソッド グループである場合は、識別し、インスタンス メソッド、デリゲートを作成する対象のオブジェクト。If the argument is a method group, it identifies the method and, for an instance method, the object for which to create a delegate. 引数が匿名関数の場合、パラメーターと、デリゲート ターゲットのメソッド本体が直接定義します。If the argument is an anonymous function it directly defines the parameters and method body of the delegate target. 引数が値の場合、コピーを作成するためのデリゲート インスタンスを識別します。If the argument is a value it identifies a delegate instance of which to create a copy.

場合、コンパイル時の型を持つdynamicdelegate_creation_expressionが動的にバインドされている (動的バインド)、および次の規則実行時の型を使用して実行時に適用されます、します。If the expression has the compile-time type dynamic, the delegate_creation_expression is dynamically bound (Dynamic binding), and the rules below are applied at run-time using the run-time type of the expression. それ以外の場合、ルールは、コンパイル時に適用されます。Otherwise the rules are applied at compile-time.

バインド時の処理、 delegate_creation_expressionフォームのnew D(E)ここで、Dは、 delegate_typeEは、、次の手順で構成されます。The binding-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:

  • 場合Eはメソッド グループでは、デリゲート作成式はメソッド グループ変換と同じ方法で処理 (メソッド グループ変換) からEDします。If E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
  • 場合E、匿名関数は、匿名関数の変換と同じ方法でデリゲート作成式が処理される (匿名関数の変換) からEDします。If E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
  • 場合E、値は、E互換である必要があります (デリゲートの宣言) とD、され、結果は新しく作成された型のデリゲートへの参照をD同じ呼び出しを参照ボックスの一覧としてEします。If E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. 場合Eと互換性がないDコンパイル時エラーが発生します。If E is not compatible with D, a compile-time error occurs.

実行時の処理、 delegate_creation_expressionフォームのnew D(E)ここで、Dは、 delegate_typeEは、、次の手順で構成されます。The run-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:

  • 場合Eはメソッド グループでは、メソッド グループ変換としてデリゲート作成式が評価されます (メソッド グループ変換) からEDします。If E is a method group, the delegate creation expression is evaluated as a method group conversion (Method group conversions) from E to D.
  • 場合E、匿名関数は、デリゲートの作成は、匿名関数の変換からとして評価されます。ED(匿名関数の変換)。If E is an anonymous function, the delegate creation is evaluated as an anonymous function conversion from E to D (Anonymous function conversions).
  • 場合Eの値であり、 delegate_type:If E is a value of a delegate_type:
    • E 評価されます。E is evaluated. この評価は、例外を発生させ、その後の手順は実行されません。If this evaluation causes an exception, no further steps are executed.
    • 場合の値EnullSystem.NullReferenceExceptionがスローされます、以降の手順は実行されません。If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
    • デリゲート型の新しいインスタンスDが割り当てられます。A new instance of the delegate type D is allocated. 新しいインスタンスを割り当てることができる十分なメモリがない場合、System.OutOfMemoryExceptionがスローされます、以降の手順は実行されません。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
    • 指定されたデリゲート インスタンスと同じ呼び出しリストを持つ新しいデリゲート インスタンスが初期化されてEします。The new delegate instance is initialized with the same invocation list as the delegate instance given by E.

デリゲートがインスタンス化され、デリゲートの有効期間にわたって一定時に、デリゲートの呼び出しリストが決まります。The invocation list of a delegate is determined when the delegate is instantiated and then remains constant for the entire lifetime of the delegate. つまりが作成されたら、デリゲートの呼び出し可能なターゲット エンティティを変更することはできません。In other words, it is not possible to change the target callable entities of a delegate once it has been created. ときに 2 つのデリゲートを組み合わせるか、別の 1 つが削除された (デリゲートの宣言)、新しいデリゲートの結果は、既存のデリゲートには、その内容が変更はありません。When two delegates are combined or one is removed from another (Delegate declarations), a new delegate results; no existing delegate has its contents changed.

場合によっては、プロパティ、インデクサー、ユーザー定義演算子、インスタンス コンス トラクター、デストラクター、または静的コンス トラクターを参照するデリゲートを作成することはできません。It is not possible to create a delegate that refers to a property, indexer, user-defined operator, instance constructor, destructor, or static constructor.

前述のように、デリゲートがから作成するとき、メソッド グループ、仮パラメーター リストと、デリゲートの戻り値の型を特定のオーバー ロードされたメソッドを選択します。As described above, when a delegate is created from a method group, the formal parameter list and return type of the delegate determine which of the overloaded methods to select. In the example

delegate double DoubleFunc(double x);

class A
{
    DoubleFunc f = new DoubleFunc(Square);

    static float Square(float x) {
        return x * x;
    }

    static double Square(double x) {
        return x * x;
    }
}

A.fフィールドは、2 つ目を参照するデリゲートを使用して初期化Squareメソッド メソッドは、仮パラメーター リストおよび戻り値の型に正確に一致するため、DoubleFuncします。the A.f field is initialized with a delegate that refers to the second Square method because that method exactly matches the formal parameter list and return type of DoubleFunc. 2 つ目がSquareメソッドが存在していない、コンパイル時エラーが発生します。Had the second Square method not been present, a compile-time error would have occurred.

匿名のオブジェクト作成式Anonymous object creation expressions

Anonymous_object_creation_expression匿名型のオブジェクトを作成するために使用します。An anonymous_object_creation_expression is used to create an object of an anonymous type.

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
    | base_access
    | null_conditional_member_access
    | identifier '=' expression
    ;

匿名オブジェクト初期化子は、匿名型を宣言し、その型のインスタンスを返します。An anonymous object initializer declares an anonymous type and returns an instance of that type. 匿名型は、名前のないクラス型から直接継承されるobjectします。An anonymous type is a nameless class type that inherits directly from object. 匿名型のメンバーは、一連の型のインスタンスを作成するために使用する匿名オブジェクト初期化子から推論される読み取り専用プロパティです。The members of an anonymous type are a sequence of read-only properties inferred from the anonymous object initializer used to create an instance of the type. フォームの匿名オブジェクト初期化子具体的には、Specifically, an anonymous object initializer of the form

new { p1 = e1, p2 = e2, ..., pn = en }

フォームの匿名型を宣言します。declares an anonymous type of the form

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します。where each Tx is the type of the corresponding expression ex. 使用される式をmember_declarator型である必要があります。The expression used in a member_declarator must have a type. したがって、式のコンパイル時エラーが、 member_declaratorを null または匿名関数です。Thus, it is a compile-time error for an expression in a member_declarator to be null or an anonymous function. 安全でない型を持つ式のコンパイル時エラーです。It is also a compile-time error for the expression to have an unsafe type.

匿名型のパラメーターの名前、Equalsメソッドは、コンパイラによって自動的に生成され、プログラム テキストでは参照できません。The names of an anonymous type and of the parameter to its Equals method are automatically generated by the compiler and cannot be referenced in program text.

同じ順序で一連のコンパイル時の型と同じ名前のプロパティを指定する 2 つの匿名オブジェクト初期化子では、同じプログラム内で、同じ匿名型のインスタンスが生成されます。Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.

In the example

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

ため、最後の行で割り当てが許可p1p2が同じ匿名型。the assignment on the last line is permitted because p1 and p2 are of the same anonymous type.

EqualsGetHashcode匿名型のメソッドから継承されたメソッドをオーバーライドobjectの観点で定義されていると、EqualsGetHashcodeプロパティの同じ匿名型の 2 つのインスタンスが等しくないように場合そのすべてのプロパティが等しい場合のみです。The Equals and GetHashcode methods on anonymous types override the methods inherited from object, and are defined in terms of the Equals and GetHashcode of the properties, so that two instances of the same anonymous type are equal if and only if all their properties are equal.

メンバー宣言子は、簡易名を省略できます (型推論)、メンバー アクセス (コンパイル時の動的なオーバー ロードの解決の確認)、ベース アクセス (へのアクセスの基本)または、null 条件メンバー アクセス (プロジェクション初期化子として Null 条件式)。A member declarator can be abbreviated to a simple name (Type inference), a member access (Compile-time checking of dynamic overload resolution), a base access (Base access) or a null-conditional member access (Null-conditional expressions as projection initializers). これと呼ばれますが、プロジェクション初期化子の宣言と同じ名前のプロパティへの代入を短縮したものとします。This is called a projection initializer and is shorthand for a declaration of and assignment to a property with the same name. 具体的には、フォームのメンバー宣言の子Specifically, member declarators of the forms

identifier
expr.identifier

それぞれ、次に、まったく同じです。are precisely equivalent to the following, respectively:

identifier = identifier
identifier = expr.identifier

そのため、プロジェクション初期化子で、識別子値とフィールドまたは値が割り当てられているプロパティを選択します。Thus, in a projection initializer the identifier selects both the value and the field or property to which the value is assigned. 直感的には、プロジェクション初期化子は、値だけでなく、値の名前を射影します。Intuitively, a projection initializer projects not just a value, but also the name of the value.

Typeof 演算子The typeof operator

typeof演算子を使用して、取得、System.Type型のオブジェクト。The typeof operator is used to obtain the System.Type object for a type.

typeof_expression
    : 'typeof' '(' type ')'
    | 'typeof' '(' unbound_type_name ')'
    | 'typeof' '(' 'void' ')'
    ;

unbound_type_name
    : identifier generic_dimension_specifier?
    | identifier '::' identifier generic_dimension_specifier?
    | unbound_type_name '.' identifier generic_dimension_specifier?
    ;

generic_dimension_specifier
    : '<' comma* '>'
    ;

comma
    : ','
    ;

最初のフォームtypeof_expressionから成る、typeofキーワードの後に、かっこで囲まれたします。The first form of typeof_expression consists of a typeof keyword followed by a parenthesized type. この形式の式の結果は、System.Type示された型のオブジェクト。The result of an expression of this form is the System.Type object for the indicated type. 1 つしかないSystem.Type指定された型のオブジェクト。There is only one System.Type object for any given type. これにより、型の Ttypeof(T) == typeof(T)は常に true です。This means that for a type T, typeof(T) == typeof(T) is always true. することはできませんdynamicします。The type cannot be dynamic.

2 番目の形式のtypeof_expressionから成る、typeofキーワードの後に、かっこで囲まれたunbound_type_nameします。The second form of typeof_expression consists of a typeof keyword followed by a parenthesized unbound_type_name. Unbound_type_nameとよく似ていますが、 type_name (Namespace と型の名前) ことを除いて、 unbound_type_nameが含まれていますgeneric_dimension_specifiers をtype_nameが含まれていますtype_argument_list秒。An unbound_type_name is very similar to a type_name (Namespace and type names) except that an unbound_type_name contains generic_dimension_specifiers where a type_name contains type_argument_lists. ときのオペランドをtypeof_expressionを両方の文法を満たす一連のトークンは、 unbound_type_nametype_name、つまりそれが含まれる場合どちらも、 generic_dimension_specifiertype_argument_list、トークンのシーケンスがあると見なされます、 type_nameします。When the operand of a typeof_expression is a sequence of tokens that satisfies the grammars of both unbound_type_name and type_name, namely when it contains neither a generic_dimension_specifier nor a type_argument_list, the sequence of tokens is considered to be a type_name. 意味、 unbound_type_nameは次のように決定されます。The meaning of an unbound_type_name is determined as follows:

  • トークンのシーケンスに変換をtype_nameそれぞれを置き換えることで、 generic_dimension_specifierで、 type_argument_listことと同じ数のコンマとキーワードobjectとして各type_argumentします。Convert the sequence of tokens to a type_name by replacing each generic_dimension_specifier with a type_argument_list having the same number of commas and the keyword object as each type_argument.
  • 結果を評価type_name、中に、すべての型パラメーターの制約は無視されます。Evaluate the resulting type_name, while ignoring all type parameter constraints.
  • Unbound_type_name構築された型に関連付けられているバインドされていないジェネリック型に解決される (バインドされ、型がバインドされていない)。The unbound_type_name resolves to the unbound generic type associated with the resulting constructed type (Bound and unbound types).

結果、 typeof_expressionは、System.Typeオブジェクトのジェネリック型がバインドされていない結果します。The result of the typeof_expression is the System.Type object for the resulting unbound generic type.

3 番目の形式typeof_expressionから成る、typeofキーワードの後に、かっこで囲まれたvoidキーワード。The third form of typeof_expression consists of a typeof keyword followed by a parenthesized void keyword. この形式の式の結果は、System.Typeがない場合、型を表すオブジェクト。The result of an expression of this form is the System.Type object that represents the absence of a type. によって返される型オブジェクトtypeof(void)任意の型に対して返される型のオブジェクトとは異なります。The type object returned by typeof(void) is distinct from the type object returned for any type. この特別な種類のオブジェクトは、言語では、メソッドにリフレクションを使用できるようにするのインスタンスとの void メソッドを含む、任意のメソッドの戻り値の型を表す方法があるクラス ライブラリで役立ちますSystem.Typeします。This special type object is useful in class libraries that allow reflection onto methods in the language, where those methods wish to have a way to represent the return type of any method, including void methods, with an instance of System.Type.

typeof演算子は、型パラメーターで使用できます。The typeof operator can be used on a type parameter. 結果は、System.Type型パラメーターにバインドされていた、実行時の型のオブジェクト。The result is the System.Type object for the run-time type that was bound to the type parameter. typeof演算子は、構築された型またはバインドされていないジェネリック型でも使用できます (バインドされ、型がバインドされていない)。The typeof operator can also be used on a constructed type or an unbound generic type (Bound and unbound types). System.Type 、バインドされていないジェネリック型が同じオブジェクト、System.Typeインスタンス型のオブジェクト。The System.Type object for an unbound generic type is not the same as the System.Type object of the instance type. インスタンスの型は常に実行時に構築されたクローズ型ためそのSystem.Typeオブジェクトは、バインドされていないジェネリック型に型引数があるないときに使用して、実行時の型引数に依存します。The instance type is always a closed constructed type at run-time so its System.Type object depends on the run-time type arguments in use, while the unbound generic type has no type arguments.

例では、The example

using System;

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();
    }
}

次の出力が生成されます。produces the following output:

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]

なおintSystem.Int32は同じ型。Note that int and System.Int32 are the same type.

また、結果のtypeof(X<>)型引数がの結果に依存しませんtypeof(X<T>)は。Also note that the result of typeof(X<>) does not depend on the type argument but the result of typeof(X<T>) does.

checked 演算子と unchecked 演算子The checked and unchecked operators

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

checked_expression
    : 'checked' '(' expression ')'
    ;

unchecked_expression
    : 'unchecked' '(' expression ')'
    ;

checked演算子が checked コンテキストで含まれている式を評価し、unchecked演算子が unchecked コンテキストで含まれている式を評価します。The checked operator evaluates the contained expression in a checked context, and the unchecked operator evaluates the contained expression in an unchecked context. A checked_expressionまたはunchecked_expressionに対応して、 parenthesized_expression (のかっこで囲まれた式) が含まれている式は、特定のオーバーフロー チェック コンテキストで評価されます。A checked_expression or unchecked_expression corresponds exactly to a parenthesized_expression (Parenthesized expressions), except that the contained expression is evaluated in the given overflow checking context.

オーバーフロー チェック コンテキストを制御することも、checkeduncheckedステートメント (checked と unchecked ステートメント)。The overflow checking context can also be controlled through the checked and unchecked statements (The checked and unchecked statements).

オーバーフロー チェック コンテキストを確立して、次の操作が影響を受ける、checkedunchecked演算子およびステートメント。The following operations are affected by the overflow checking context established by the checked and unchecked operators and statements:

大きすぎて、変換先の型、操作が実行されるコントロールでありコンテキストの結果の動作を表すである結果を生成、上述の操作のいずれかの場合。When one of the above operations produce a result that is too large to represent in the destination type, the context in which the operation is performed controls the resulting behavior:

  • checkedコンテキスト、操作が定数式である場合 (定数式)、コンパイル時エラーが発生します。In a checked context, if the operation is a constant expression (Constant expressions), a compile-time error occurs. それ以外の場合、実行時に、操作が実行されると、System.OverflowExceptionがスローされます。Otherwise, when the operation is performed at run-time, a System.OverflowException is thrown.
  • uncheckedコンテキスト、結果は変換先の型に収まらない上位ビットが破棄されてによって切り捨てられます。In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type.

非定数式 (実行時に評価される式) のいずれかで囲まれていないcheckedまたはunchecked演算子またはステートメントでは、既定のオーバーフロー チェック コンテキストは、 unchecked (コンパイラなどの外部要因しない限り、スイッチと実行環境の構成) の呼び出しのchecked評価します。For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation.

定数式 (コンパイル時に完全に評価される式)、既定のオーバーフロー チェック コンテキストは常にcheckedします。For constant expressions (expressions that can be fully evaluated at compile-time), the default overflow checking context is always checked. 定数式を明示的に配置しない限り、uncheckedコンテキストでは、常に式のコンパイル時の評価中に発生するオーバーフローにコンパイル時エラーが発生します。Unless a constant expression is explicitly placed in an unchecked context, overflows that occur during the compile-time evaluation of the expression always cause compile-time errors.

匿名関数の本体は受けませんcheckedまたはunchecked匿名関数が発生するコンテキスト。The body of an anonymous function is not affected by checked or unchecked contexts in which the anonymous function occurs.

In the example

class Test
{
    static readonly int x = 1000000;
    static readonly int y = 1000000;

    static int F() {
        return checked(x * y);      // Throws OverflowException
    }

    static int G() {
        return unchecked(x * y);    // Returns -727379968
    }

    static int H() {
        return x * y;               // Depends on default
    }
}

コンパイル時に評価される式のどちらでもないために、コンパイル時エラーは報告されません。no compile-time errors are reported since neither of the expressions can be evaluated at compile-time. 実行時、Fメソッドがスローされます、 System.OverflowException、およびG-727379968 (範囲外の結果の下位 32 ビット) を返します。At run-time, the F method throws a System.OverflowException, and the G method returns -727379968 (the lower 32 bits of the out-of-range result). 動作、Hメソッドは、既定のオーバーフロー チェック コンテキストをコンパイル時にによって異なりますが、これと同じであるかFまたは同じGします。The behavior of the H method depends on the default overflow checking context for the compilation, but it is either the same as F or the same as G.

In the example

class Test
{
    const int x = 1000000;
    const int y = 1000000;

    static int F() {
        return checked(x * y);      // Compile error, overflow
    }

    static int G() {
        return unchecked(x * y);    // Returns -727379968
    }

    static int H() {
        return x * y;               // Compile error, overflow
    }
}

内の定数式を評価するときに発生するオーバーフローFHで式を評価するために報告されることをコンパイル時エラーが発生する、checkedコンテキスト。the overflows that occur when evaluating the constant expressions in F and H cause compile-time errors to be reported because the expressions are evaluated in a checked context. 定数式を評価するときにも、オーバーフローが発生G評価が行われるので、uncheckedコンテキスト、オーバーフローが報告されません。An overflow also occurs when evaluating the constant expression in G, but since the evaluation takes place in an unchecked context, the overflow is not reported.

checkedunchecked演算子、オーバーフロー チェック コンテキスト内でテキストに含まれるこれらの操作の影響を受けるのみ、"(「と」)"トークンです。The checked and unchecked operators only affect the overflow checking context for those operations that are textually contained within the "(" and ")" tokens. 演算子は、式を評価した結果として呼び出される関数メンバーに影響を与えるありません。The operators have no effect on function members that are invoked as a result of evaluating the contained expression. In the example

class Test
{
    static int Multiply(int x, int y) {
        return x * y;
    }

    static int F() {
        return checked(Multiply(1000000, 1000000));
    }
}

使用checkedFの評価には影響しませんx * yMultiplyため、x * yは既定のオーバーフロー チェック コンテキストで評価されます。the use of checked in F does not affect the evaluation of x * y in Multiply, so x * y is evaluated in the default overflow checking context.

unchecked演算子は、16 進数表記で符号付き整数型の定数を記述するときに便利です。The unchecked operator is convenient when writing constants of the signed integral types in hexadecimal notation. 例:For example:

class Test
{
    public const int AllBits = unchecked((int)0xFFFFFFFF);

    public const int HighBit = unchecked((int)0x80000000);
}

上記の 16 進定数の両方が型のuintします。Both of the hexadecimal constants above are of type uint. 定数に含まれないため、intせず、範囲、unchecked演算子、キャストをintコンパイル時エラーが生成されます。Because the constants are outside the int range, without the unchecked operator, the casts to int would produce compile-time errors.

checkedunchecked演算子とステートメントは、数値計算をいくつかの特定の側面を制御するプログラマを許可します。The checked and unchecked operators and statements allow programmers to control certain aspects of some numeric calculations. ただし、一部の数値演算子の動作は、そのオペランドのデータ型によって異なります。However, the behavior of some numeric operators depends on their operands' data types. たとえば、小数点以下 2 桁を常に乗算することで例外が発生オーバーフロー内でも、明示的にuncheckedを構築します。For example, multiplying two decimals always results in an exception on overflow even within an explicitly unchecked construct. 同様に、2 つの乗算フローティング状態になったことはありません結果オーバーフロー例外は発生内でも、明示的にcheckedを構築します。Similarly, multiplying two floats never results in an exception on overflow even within an explicitly checked construct. さらに、その他の演算子はチェックのモードで影響しない、既定のかどうか、または明示的な。In addition, other operators are never affected by the mode of checking, whether default or explicit.

既定値の式Default value expressions

既定値の式は、既定値を取得するために使用 (既定値) の型。A default value expression is used to obtain the default value (Default values) of a type. 通常、可能性がありますが認識されていない場合は、型パラメーターが値型または参照型であるため、型パラメーターの既定値の式が使用されます。Typically a default value expression is used for type parameters, since it may not be known if the type parameter is a value type or a reference type. (から変換が存在しない、null型パラメーターが参照型とわかっている場合を除き、型パラメーターにリテラルです)。(No conversion exists from the null literal to a type parameter unless the type parameter is known to be a reference type.)

default_value_expression
    : 'default' '(' type ')'
    ;

場合、で、 default_value_expression評価参照型には、実行時に、結果がnullその型に変換します。If the type in a default_value_expression evaluates at run-time to a reference type, the result is null converted to that type. 場合、で、 default_value_expression評価値の型には、実行時に、結果が、 value_typeの既定値 (既定コンス トラクター)。If the type in a default_value_expression evaluates at run-time to a value type, the result is the value_type's default value (Default constructors).

A default_value_expression定数式です (定数式) 場合は、型が参照型または参照型があることがわかっている型パラメーター (型パラメーター制約)。A default_value_expression is a constant expression (Constant expressions) if the type is a reference type or a type parameter that is known to be a reference type (Type parameter constraints). さらに、 default_value_expression定数式は、型は、次の値の型のいずれかの場合: sbytebyteshortushortintuintlongulongcharfloatdoubledecimalbool、または列挙型。In addition, a default_value_expression is a constant expression if the type is one of the following value types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, or any enumeration type.

Nameof 式Nameof expressions

A nameof_expression文字列定数としてプログラム エンティティの名前を取得するために使用します。A nameof_expression is used to obtain the name of a program entity as a constant string.

nameof_expression
    : 'nameof' '(' named_entity ')'
    ;

named_entity
    : simple_name
    | named_entity_target '.' identifier type_argument_list?
    ;

named_entity_target
    : 'this'
    | 'base'
    | named_entity 
    | predefined_type 
    | qualified_alias_member
    ;

文法的に言うと、 named_entityオペランドが式では常にします。Grammatically speaking, the named_entity operand is always an expression. nameofは予約済みキーワードの場合は、nameof 式は、簡易名の呼び出しで構文的にあいまいな常にnameofします。Because nameof is not a reserved keyword, a nameof expression is always syntactically ambiguous with an invocation of the simple name nameof. 互換性の理由から、名の参照の場合 (簡易名) 名のnameof成功すると、式として扱われます、 invocation_expression呼び出しは、かどうかに関係なく--法律です。For compatibility reasons, if a name lookup (Simple names) of the name nameof succeeds, the expression is treated as an invocation_expression -- regardless of whether the invocation is legal. それ以外の場合は、 nameof_expressionします。Otherwise it is a nameof_expression.

意味、 named_entitynameof_expressionことの意味を式としては、いずれかとして、 simple_namebase_accessまたはmember_accessします。The meaning of the named_entity of a nameof_expression is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. ただし、場所、ルックアップで説明されている簡易名メンバー アクセス静的においては、インスタンス メンバーが見つかったため、エラーが発生、 nameof_expressionこのようなエラーを生成しません。However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.

コンパイル時エラーには、 named_entityが、メソッド グループを指定する、 type_argument_listします。It is a compile-time error for a named_entity designating a method group to have a type_argument_list. コンパイル時間のエラーには、 named_entity_targetに、型を持つdynamicします。It is a compile time error for a named_entity_target to have the type dynamic.

A nameof_expression型の定数式は、 string、実行時に影響しません。A nameof_expression is a constant expression of type string, and has no effect at runtime. 具体的には、そのnamed_entityは評価されず、および限定代入分析の目的では無視されます (単純式での一般的な規則)。Specifically, its named_entity is not evaluated, and is ignored for the purposes of definite assignment analysis (General rules for simple expressions). その値の最後の識別子では、 named_entity 、省略可能な最後の前にtype_argument_list、次のように変換されました。Its value is the last identifier of the named_entity before the optional final type_argument_list, transformed in the following way:

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

これらは、同じ変換の適用識別子識別子の間に等しいかどうかをテストするときにします。These are the same transformations applied in Identifiers when testing equality between identifiers.

TODO: 例TODO: examples

匿名メソッド式Anonymous method expressions

Anonymous_method_expression匿名関数を定義する 2 つの方法の 1 つです。An anonymous_method_expression is one of two ways of defining an anonymous function. さらに詳細は匿名関数式します。These are further described in Anonymous function expressions.

単項演算子Unary operators

?+-!~++--キャスト、およびawait演算子は、単項演算子と呼ばれます。The ?, +, -, !, ~, ++, --, cast, and await operators are called the unary operators.

unary_expression
    : primary_expression
    | null_conditional_expression
    | '+' unary_expression
    | '-' unary_expression
    | '!' unary_expression
    | '~' unary_expression
    | pre_increment_expression
    | pre_decrement_expression
    | cast_expression
    | await_expression
    | unary_expression_unsafe
    ;

場合のオペランドをunary_expressionコンパイル時の型を持つdynamic、動的にバインドされている (動的バインド)。If the operand of a unary_expression has the compile-time type dynamic, it is dynamically bound (Dynamic binding). この場合、コンパイル時はの入力、 unary_expressiondynamic、オペランドの実行時の型を使用して実行時に以下に示す解決が行わします。In this case the compile-time type of the unary_expression is dynamic, and the resolution described below will take place at run-time using the run-time type of the operand.

Null 条件演算子Null-conditional operator

Null 条件演算子では、そのオペランドが null でない場合にのみに、操作の一覧が、オペランドに適用されます。The null-conditional operator applies a list of operations to its operand only if that operand is non-null. それ以外の場合は、演算子を適用した結果、nullします。Otherwise the result of applying the operator is null.

null_conditional_expression
    : primary_expression null_conditional_operations
    ;

null_conditional_operations
    : null_conditional_operations? '?' '.' identifier type_argument_list?
    | null_conditional_operations? '?' '[' argument_list ']'
    | null_conditional_operations '.' identifier type_argument_list?
    | null_conditional_operations '[' argument_list ']'
    | null_conditional_operations '(' argument_list? ')'
    ;

操作の一覧には、メンバー アクセスと要素アクセス操作 (これは、null 条件自体である可能性があります)、だけでなく、呼び出しを含めることができます。The list of operations can include member access and element access operations (which may themselves be null-conditional), as well as invocation.

たとえば、式a.b?[0]?.c()は、 null_conditional_expressionで、 primary_expression a.bnull_conditional_operations ?[0] (要素の null 条件付きアクセス)、 ?.c (null 条件メンバー アクセス) および()(呼び出し)。For example, the expression a.b?[0]?.c() is a null_conditional_expression with a primary_expression a.b and null_conditional_operations ?[0] (null-conditional element access), ?.c (null-conditional member access) and () (invocation).

Null_conditional_expression Eで、 primary_expression PE0ヘッダーファイル リード削除することで取得した式を指定する?のそれぞれから、 null_conditional_operationsEがある 1 つ。For a null_conditional_expression E with a primary_expression P, let E0 be the expression obtained by textually removing the leading ? from each of the null_conditional_operations of E that have one. 概念的には、E0によって表される null チェックの場合に評価される式です、 ?s は検索、nullします。Conceptually, E0 is the expression that will be evaluated if none of the null checks represented by the ?s do find a null.

を描く遷移E1ヘッダーファイル先頭削除することで取得した式を指定する?のみからの最初、 null_conditional_operationsEします。Also, let E1 be the expression obtained by textually removing the leading ? from just the first of the null_conditional_operations in E. これが生じる、プライマリ式(1 つだけを使用する必要がある場合?) または別null_conditional_expressionします。This may lead to a primary-expression (if there was just one ?) or to another null_conditional_expression.

たとえば場合、E式ですa.b?[0]?.c()、しE0式ですa.b[0].c()E1式は、a.b[0]?.c()します。For example, if E is the expression a.b?[0]?.c(), then E0 is the expression a.b[0].c() and E1 is the expression a.b[0]?.c().

場合E0し、何もとして分類されますEnothing として分類されます。If E0 is classified as nothing, then E is classified as nothing. それ以外の場合、E は値として分類されます。Otherwise E is classified as a value.

E0 E1の意味を判断するために使用E:E0 and E1 are used to determine the meaning of E:

  • 場合Eとして発生するstatement_expressionの意味Eステートメントと同じですIf E occurs as a statement_expression the meaning of E is the same as the statement

    if ((object)P != null) E1;
    

    P は 1 回だけ評価されることを除きます。except that P is evaluated only once.

  • の場合E0コンパイル時エラーが発生した nothing として分類されます。Otherwise, if E0 is classified as nothing a compile-time error occurs.

  • それ以外の場合、ようにT0の型であるE0します。Otherwise, let T0 be the type of E0.

    • 場合T0型パラメーターには、参照型または null 非許容値型では、コンパイル時エラーが発生したが不明です。If T0 is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.

    • 場合T0null 非許容値型では、次の種類はET0?との意味Eと同じですIf T0 is a non-nullable value type, then the type of E is T0?, and the meaning of E is the same as

      ((object)P == null) ? (T0?)null : E1
      

      点を除いてPは 1 回だけ評価されます。except that P is evaluated only once.

    • それ以外の場合、電子メールの種類は、T0、および電子メールの意味は同じOtherwise the type of E is T0, and the meaning of E is the same as

      ((object)P == null) ? null : E1
      

      点を除いてPは 1 回だけ評価されます。except that P is evaluated only once.

場合E1自体では、 null_conditional_expression、し、この規則が適用されます、もう一度のテストを入れ子nullなくなるまで?の式が、一番下まで減少したとプライマリ式にE0します。If E1 is itself a null_conditional_expression, then these rules are applied again, nesting the tests for null until there are no further ?'s, and the expression has been reduced all the way down to the primary-expression E0.

たとえば場合、式a.b?[0]?.c()ステートメントのようにステートメントの式、として発生します。For example, if the expression a.b?[0]?.c() occurs as a statement-expression, as in the statement:

a.b?[0]?.c();

その意味と同等です。its meaning is equivalent to:

if (a.b != null) a.b[0]?.c();

もう一度と同等です。which again is equivalent to:

if (a.b != null) if (a.b[0] != null) a.b[0].c();

点を除いてa.ba.b[0]1 回だけ評価されます。Except that a.b and a.b[0] are evaluated only once.

場合に、その値が使用されているでのコンテキストで行われます。If it occurs in a context where its value is used, as in:

var x = a.b?[0]?.c();

その意味と等価の最後の呼び出しの種類が null 非許容値型がない、.and assuming that the type of the final invocation is not a non-nullable value type, its meaning is equivalent to:

var x = (a.b == null) ? null : (a.b[0] == null) ? null : a.b[0].c();

点を除いてa.ba.b[0]1 回だけ評価されます。except that a.b and a.b[0] are evaluated only once.

プロジェクション初期化子として null 条件式Null-conditional expressions as projection initializers

Null 条件式としてのみ使用できます、 member_declaratorで、 anonymous_object_creation_expression (匿名オブジェクト作成式) 場合(null 条件の必要に応じて) メンバー アクセスで終了します。A null-conditional expression is only allowed as a member_declarator in an anonymous_object_creation_expression (Anonymous object creation expressions) if it ends with an (optionally null-conditional) member access. 文法的に、この要件は、として表現できます。Grammatically, this requirement can be expressed as:

null_conditional_member_access
    : primary_expression null_conditional_operations? '?' '.' identifier type_argument_list?
    | primary_expression null_conditional_operations '.' identifier type_argument_list?
    ;

これは、特殊なケースの文法のnull_conditional_expression上。This is a special case of the grammar for null_conditional_expression above. 運用member_declarator匿名オブジェクト作成式のみを含む、 null_conditional_member_accessします。The production for member_declarator in Anonymous object creation expressions then includes only null_conditional_member_access.

ステートメントの式と null 条件式Null-conditional expressions as statement expressions

Null 条件式としてのみ使用できます、 statement_expression (式ステートメント) 場合は、呼び出しで終了します。A null-conditional expression is only allowed as a statement_expression (Expression statements) if it ends with an invocation. 文法的に、この要件は、として表現できます。Grammatically, this requirement can be expressed as:

null_conditional_invocation_expression
    : primary_expression null_conditional_operations '(' argument_list? ')'
    ;

これは、特殊なケースの文法のnull_conditional_expression上。This is a special case of the grammar for null_conditional_expression above. 運用statement_expression式ステートメントのみを含む、 null_conditional_invocation_expressionします。The production for statement_expression in Expression statements then includes only null_conditional_invocation_expression.

単項プラス演算子Unary plus operator

フォームの操作の+x、単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form +x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. 定義済みの単項プラス演算子は。The predefined unary plus operators are:

int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);

これらの演算子のそれぞれについて、単に、オペランドの値になります。For each of these operators, the result is simply the value of the operand.

単項マイナス演算子Unary minus operator

フォームの操作の-x、単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form -x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. 定義済みの否定演算子は次のとおりです。The predefined negation operators are:

  • 整数の否定:Integer negation:

    int operator -(int x);
    long operator -(long x);
    

    結果を差し引いて計算xゼロから。The result is computed by subtracting x from zero. 場合の値xオペランドの型の表現可能な最小の値は、(-2 ^31intまたは-2 ^63 long) の算術否定しxオペランドの型で表すことはできません。If the value of x is the smallest representable value of the operand type (-2^31 for int or -2^63 for long), then the mathematical negation of x is not representable within the operand type. 内でこのような場合、checkedコンテキスト、System.OverflowExceptionスロー; 内に発生する場合は、uncheckedコンテキスト、結果はオペランドの値と、オーバーフローが報告されません。If this occurs within a checked context, a System.OverflowException is thrown; if it occurs within an unchecked context, the result is the value of the operand and the overflow is not reported.

    あるかどうか、否定演算子のオペランドも型uint、型に変換されますlong、および結果の型はlongします。If the operand of the negation operator is of type uint, it is converted to type long, and the type of the result is long. 例外は、許可するルール、 int -2147483648 の値 (-2 ^31)、10 進数の整数リテラルとして記述すること (整数リテラル)。An exception is the rule that permits the int value -2147483648 (-2^31) to be written as a decimal integer literal (Integer literals).

    あるかどうか、否定演算子のオペランドも型ulongコンパイル時エラーが発生します。If the operand of the negation operator is of type ulong, a compile-time error occurs. 例外は、許可するルール、long値-9223372036854775808 (-2 ^63)、10 進数の整数リテラルとして記述すること (整数リテラル)。An exception is the rule that permits the long value -9223372036854775808 (-2^63) to be written as a decimal integer literal (Integer literals).

  • 浮動小数点の否定:Floating-point negation:

    float operator -(float x);
    double operator -(double x);
    

    結果の値は、x符号を反転させたとします。The result is the value of x with its sign inverted. 場合xが NaN の場合、結果が NaN でも。If x is NaN, the result is also NaN.

  • 10 進数の否定:Decimal negation:

    decimal operator -(decimal x);
    

    結果を差し引いて計算xゼロから。The result is computed by subtracting x from zero. 10 進数の否定は、単項マイナス型の演算子を使用すると、System.Decimalします。Decimal negation is equivalent to using the unary minus operator of type System.Decimal.

論理否定演算子Logical negation operator

フォームの操作の!x、単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form !x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. 1 つだけの定義済みの論理否定演算子が存在します。Only one predefined logical negation operator exists:

bool operator !(bool x);

この演算子はオペランドの論理否定演算を計算します。オペランドが場合true、結果はfalseします。This operator computes the logical negation of the operand: If the operand is true, the result is false. オペランドが場合false、結果はtrueします。If the operand is false, the result is true.

ビットごとの補数演算子Bitwise complement operator

フォームの操作の~x、単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form ~x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. 定義済みのビットごとの補数演算子は次のとおりです。The predefined bitwise complement operators are:

int operator ~(int x);
uint operator ~(uint x);
long operator ~(long x);
ulong operator ~(ulong x);

操作の結果のビットごとの補数はこれらの演算子のそれぞれについて、xします。For each of these operators, the result of the operation is the bitwise complement of x.

すべての列挙型E暗黙的に次のビットごとの補数演算子を提供します。Every enumeration type E implicitly provides the following bitwise complement operator:

E operator ~(E x);

評価結果~xここで、x列挙型の式を指定E基になる型U、評価と同じでは正確に(E)(~(U)x)ことを除いてへの変換Eはとして常に実行される場合は、uncheckedコンテキスト (checked と unchecked 演算子)。The result of evaluating ~x, where x is an expression of an enumeration type E with an underlying type U, is exactly the same as evaluating (E)(~(U)x), except that the conversion to E is always performed as if in an unchecked context (The checked and unchecked operators).

前置インクリメント演算子と前置デクリメント演算子Prefix increment and decrement operators

pre_increment_expression
    : '++' unary_expression
    ;

pre_decrement_expression
    : '--' unary_expression
    ;

オペランドを前置インクリメントまたはデクリメントの操作が、変数、プロパティ アクセス、またはインデクサー アクセスとして分類される式をする必要があります。The operand of a prefix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. 操作の結果は、オペランドと同じ型の値です。The result of the operation is a value of the same type as the operand.

場合は、プレフィックスのオペランドがインクリメントまたはデクリメント演算は、プロパティまたはインデクサー アクセス、プロパティまたはインデクサーが両方必要、getsetアクセサー。If the operand of a prefix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. サポートしていない場合は、バインド時エラーが発生します。If this is not the case, a binding-time error occurs.

単項演算子のオーバー ロードの解決 (単項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。Unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. 定義済みの++--演算子は、次の種類の存在: sbytebyteshortushortintuintlongulongcharfloatdoubledecimal、および任意の列挙型。Predefined ++ and -- operators exist for the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, and any enum type. 定義済み++演算子がオペランドを定義済みに 1 を追加することによって生成された値を返す--演算子オペランドから 1 を引いた値を返します。The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined -- operators return the value produced by subtracting 1 from the operand. checked場合この加算または減算の結果が結果の型の範囲外と結果型が整数型または列挙型では、コンテキスト、System.OverflowExceptionがスローされます。In a checked context, if the result of this addition or subtraction is outside the range of the result type and the result type is an integral type or enum type, a System.OverflowException is thrown.

前置インクリメントの実行時の処理またはフォームの操作をデクリメント++xまたは--x次の手順で構成されています。The run-time processing of a prefix increment or decrement operation of the form ++x or --x consists of the following steps:

  • 場合x変数として分類されます。If x is classified as a variable:
    • x 変数を生成するために評価されます。x is evaluated to produce the variable.
    • 値は、選択した演算子が呼び出されるx引数として。The selected operator is invoked with the value of x as its argument.
    • 評価によって指定した位置に、演算子によって返される値が格納されているxします。The value returned by the operator is stored in the location given by the evaluation of x.
    • 演算子によって返される値は、操作の結果になります。The value returned by the operator becomes the result of the operation.
  • 場合xプロパティまたはインデクサーのアクセスに分類されます。If x is classified as a property or indexer access:
    • インスタンス式 (場合xないstatic) および引数リスト (場合xインデクサー アクセス) に関連付けられているxが評価されると、その後で、結果の使用getsetアクセサーの呼び出し。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
    • getのアクセサーxが呼び出されます。The get accessor of x is invoked.
    • 選択した演算子が呼び出されるによって返される値と、get引数にアクセサー。The selected operator is invoked with the value returned by the get accessor as its argument.
    • setのアクセサーxが呼び出されると演算子によって返される値とそのvalue引数。The set accessor of x is invoked with the value returned by the operator as its value argument.
    • 演算子によって返される値は、操作の結果になります。The value returned by the operator becomes the result of the operation.

++--演算子もサポートして後置表記法 (置インクリメント演算子と前置デクリメント演算子)。The ++ and -- operators also support postfix notation (Postfix increment and decrement operators). 結果では通常、x++またはx--の値は、x操作の前に一方の結果++xまたは--xの値は、x操作の完了後します。Typically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. いずれの場合も、x自体、操作の後に同じ値に含まれています。In either case, x itself has the same value after the operation.

operator++またはoperator--実装は、いずれかの後置または前置表記を使用して呼び出すことができます。An operator++ or operator-- implementation can be invoked using either postfix or prefix notation. 2 つの表記の個別の演算子の実装を持つことはできません。It is not possible to have separate operator implementations for the two notations.

キャスト式Cast expressions

A cast_expression式を指定した型に明示的に変換するために使用します。A cast_expression is used to explicitly convert an expression to a given type.

cast_expression
    : '(' type ')' unary_expression
    ;

A cast_expressionフォームの(T)Eここで、Tは、Eは、 unary_expression、明示的なを実行します変換 (明示的な変換) の値のE入力Tします。A cast_expression of the form (T)E, where T is a type and E is a unary_expression, performs an explicit conversion (Explicit conversions) of the value of E to type T. 明示的な変換が存在しない場合ET、バインド エラーが発生します。If no explicit conversion exists from E to T, a binding-time error occurs. それ以外の場合、結果は、明示的な変換によって生成された値になります。Otherwise, the result is the value produced by the explicit conversion. 結果は常に、値として分類場合でもE変数を表します。The result is always classified as a value, even if E denotes a variable.

文法、 cast_expression特定構文のあいまいさにつながります。The grammar for a cast_expression leads to certain syntactic ambiguities. たとえば、式(x)-yいずれかとして解釈される可能性をcast_expression (のキャスト-yを入力するx) か、または、 additive_expressionと組み合わせて、parenthesized_expression (値を計算するx - y)します。For example, the expression (x)-y could either be interpreted as a cast_expression (a cast of -y to type x) or as an additive_expression combined with a parenthesized_expression (which computes the value x - y).

解決するのにはcast_expressionあいまいさは、次のルールが存在します。1 つまたは複数のシーケンストークンs (空白) 囲まれていると見なされますの開始をかっこで囲まれた、 cast_expression次の少なくとも 1 つが true の場合にのみ。To resolve cast_expression ambiguities, the following rule exists: A sequence of one or more tokens (White space) enclosed in parentheses is considered the start of a cast_expression only if at least one of the following are true:

  • トークンのシーケンスの文法が正しいは、ではなく、します。The sequence of tokens is correct grammar for a type, but not for an expression.
  • トークンのシーケンスの文法が正しいは、、閉じかっこの直後に続くトークンは、トークンと"~"、トークン"!"、トークン"("、 識別子(Unicode 文字のエスケープ シーケンス)、リテラル(リテラル)、または anyキーワード(キーワード) を除くasisします。The sequence of tokens is correct grammar for a type, and the token immediately following the closing parentheses is the token "~", the token "!", the token "(", an identifier (Unicode character escape sequences), a literal (Literals), or any keyword (Keywords) except as and is.

トークンのシーケンスは、特定の文法的な運用環境に従う必要があるだけのことを意味上の「正しい文法」ターム。The term "correct grammar" above means only that the sequence of tokens must conform to the particular grammatical production. 構成要素である識別子の実際の意味具体的には考慮されません。It specifically does not consider the actual meaning of any constituent identifiers. たとえば場合、xyは、識別子、x.y正しい文法型の場合は、場合でもx.y型を表すは実際にします。For example, if x and y are identifiers, then x.y is correct grammar for a type, even if x.y doesn't actually denote a type.

場合、次の曖昧性除去ルールからxy識別子、 (x)y(x)(y)(x)(-y)cast_expression、s が(x)-yでない場合でもx型を識別します。From the disambiguation rule it follows that, if x and y are identifiers, (x)y, (x)(y), and (x)(-y) are cast_expressions, but (x)-y is not, even if x identifies a type. ただし場合、xは定義済みの型を識別するキーワードです (などint)、4 つの形式はcast_expressions (このようなキーワード可能性があるできなかったため、式を単独で)。However, if x is a keyword that identifies a predefined type (such as int), then all four forms are cast_expressions (because such a keyword could not possibly be an expression by itself).

Await 式Await expressions

Await 演算子は、オペランドで表される非同期操作が完了するまでに、外側の非同期関数の評価を中断に使用されます。The await operator is used to suspend evaluation of the enclosing async function until the asynchronous operation represented by the operand has completed.

await_expression
    : 'await' unary_expression
    ;

Await_expressionは非同期関数の本体でのみ使用できます (反復子)。An await_expression is only allowed in the body of an async function (Iterators). 最も外側の非同期関数では、 await_expressionこれらの場所で発生しません。Within the nearest enclosing async function, an await_expression may not occur in these places:

  • 入れ子になった (非 async) 匿名関数の内部Inside a nested (non-async) anonymous function
  • ブロックの内側、 lock_statementInside the block of a lock_statement
  • Unsafe コンテキストでIn an unsafe context

なお、 await_expression内のほとんどの場所で発生することはできません、 query_expressionものが構文的にでは、非同期ラムダ式を使用して変換されるため、します。Note that an await_expression cannot occur in most places within a query_expression, because those are syntactically transformed to use non-async lambda expressions.

非同期関数の内部でawait識別子として使用することはできません。Inside of an async function, await cannot be used as an identifier. そのため、await 式と識別子を含むさまざまな式の構文のあいまいさはありません。There is therefore no syntactic ambiguity between await-expressions and various expressions involving identifiers. 非同期関数では、外部awaitは通常の識別子として機能します。Outside of async functions, await acts as a normal identifier.

オペランドをawait_expressionと呼ばれますが、タスクします。The operand of an await_expression is called the task. 時に完了できない可能性がありますまたは可能性のある非同期操作を表す、 await_expressionが評価されます。It represents an asynchronous operation that may or may not be complete at the time the await_expression is evaluated. Await 演算子では、待機中のタスクが完了するまでに、外側の非同期関数の実行を中断し、その結果を取得します。The purpose of the await operator is to suspend execution of the enclosing async function until the awaited task is complete, and then obtain its outcome.

待機可能な式Awaitable expressions

Await 式のタスクである必要が待機可能物します。The task of an await expression is required to be awaitable. tは、次のいずれかが保持している場合は待機可能物。An expression t is awaitable if one of the following holds:

  • t コンパイル時の型です。 dynamict is of compile time type dynamic
  • t アクセス可能なインスタンスまたは拡張メソッドが呼び出されますがGetAwaiterパラメーターと型パラメーターと戻り値の型をAは次のすべてを保持します。t has an accessible instance or extension method called GetAwaiter with no parameters and no type parameters, and a return type A for which all of the following hold:
    • A インターフェイスを実装するSystem.Runtime.CompilerServices.INotifyCompletion(と呼びますINotifyCompletion簡潔にするため)A implements the interface System.Runtime.CompilerServices.INotifyCompletion (hereafter known as INotifyCompletion for brevity)
    • A インスタンスがアクセスできる、読み取り可能なプロパティを持つIsCompleted型の boolA has an accessible, readable instance property IsCompleted of type bool
    • A アクセス可能なインスタンス メソッドを持つGetResultパラメーターと型パラメーターをA has an accessible instance method GetResult with no parameters and no type parameters

目的、GetAwaiterメソッドが取得するには、 awaiterタスク。The purpose of the GetAwaiter method is to obtain an awaiter for the task. Aが呼び出されます、 awaiter 型の await 式。The type A is called the awaiter type for the await expression.

目的、IsCompletedプロパティは、タスクが完了して既にかどうかを判断します。The purpose of the IsCompleted property is to determine if the task is already complete. そうである場合、評価を中断する必要はありません。If so, there is no need to suspend evaluation.

目的、INotifyCompletion.OnCompletedメソッドが「継続」タスクをサインアップするにはデリゲートつまり (型のSystem.Action) をタスクが完了すると呼び出されます。The purpose of the INotifyCompletion.OnCompleted method is to sign up a "continuation" to the task; i.e. a delegate (of type System.Action) that will be invoked once the task is complete.

目的、GetResultメソッドは、それが完了したら、タスクの結果を取得します。The purpose of the GetResult method is to obtain the outcome of the task once it is complete. この結果、場合によっては、結果の値で正常に完了場合がありますまたはによってスローされる例外がある可能性があります、GetResultメソッド。This outcome may be successful completion, possibly with a result value, or it may be an exception which is thrown by the GetResult method.

分類の await 式Classification of await expressions

await t式と同じように分類されます(t).GetAwaiter().GetResult()します。The expression await t is classified the same way as the expression (t).GetAwaiter().GetResult(). したがって、戻り値の型の場合GetResultvoidawait_expression nothing として分類されます。Thus, if the return type of GetResult is void, the await_expression is classified as nothing. 非 void の戻り値の型がある場合Tawait_expression型の値として分類されますTします。If it has a non-void return type T, the await_expression is classified as a value of type T.

Await 式の実行時の評価Runtime evaluation of await expressions

式は、実行時にawait tは次のように評価されます。At runtime, the expression await t is evaluated as follows:

  • Awaitera式を評価することによって取得(t).GetAwaiter()します。An awaiter a is obtained by evaluating the expression (t).GetAwaiter().
  • A bool b式を評価することによって取得(a).IsCompletedします。A bool b is obtained by evaluating the expression (a).IsCompleted.
  • 場合bfalse評価がかどうかに依存し、aインターフェイスを実装するSystem.Runtime.CompilerServices.ICriticalNotifyCompletion(と呼びますICriticalNotifyCompletion簡潔にするため)。If b is false then evaluation depends on whether a implements the interface System.Runtime.CompilerServices.ICriticalNotifyCompletion (hereafter known as ICriticalNotifyCompletion for brevity). このチェックはバインドの時間で行われます実行時につまり場合aコンパイル時の型がdynamic、し、それ以外の場合コンパイル時にします。This check is done at binding time; i.e. at runtime if a has the compile time type dynamic, and at compile time otherwise. ようにr再開デリゲートを表します (反復子)。Let r denote the resumption delegate (Iterators):
    • 場合a実装しないICriticalNotifyCompletion、式、(a as (INotifyCompletion)).OnCompleted(r)が評価されます。If a does not implement ICriticalNotifyCompletion, then the expression (a as (INotifyCompletion)).OnCompleted(r) is evaluated.
    • 場合aを実装してICriticalNotifyCompletion、式、(a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r)が評価されます。If a does implement ICriticalNotifyCompletion, then the expression (a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r) is evaluated.
    • 評価が中断し、および非同期関数の現在の呼び出し元に制御が返されます。Evaluation is then suspended, and control is returned to the current caller of the async function.
  • いずれかの直後に (場合btrue)、または再開デリゲートの起動の後に (場合bfalse)、式(a).GetResult()が評価されます。Either immediately after (if b was true), or upon later invocation of the resumption delegate (if b was false), the expression (a).GetResult() is evaluated. その値がの結果で値を返された場合、 await_expressionします。If it returns a value, that value is the result of the await_expression. それ以外の場合、結果はありません。Otherwise the result is nothing.

インターフェイスのメソッドの実装を awaiter のINotifyCompletion.OnCompletedICriticalNotifyCompletion.UnsafeOnCompleted発生することは、デリゲートr多くても 1 回呼び出されます。An awaiter's implementation of the interface methods INotifyCompletion.OnCompleted and ICriticalNotifyCompletion.UnsafeOnCompleted should cause the delegate r to be invoked at most once. それ以外の場合、外側の非同期関数の動作は定義されません。Otherwise, the behavior of the enclosing async function is undefined.

算術演算子Arithmetic operators

*/%+、および-演算子は、算術演算子と呼ばれます。The *, /, %, +, and - operators are called the arithmetic operators.

multiplicative_expression
    : unary_expression
    | multiplicative_expression '*' unary_expression
    | multiplicative_expression '/' unary_expression
    | multiplicative_expression '%' unary_expression
    ;

additive_expression
    : multiplicative_expression
    | additive_expression '+' multiplicative_expression
    | additive_expression '-' multiplicative_expression
    ;

算術演算子のオペランドがコンパイル時の型を持つかどうかdynamic、式を動的にバインドし、(動的バインド)。If an operand of an arithmetic operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). この場合、式のコンパイル時の型はdynamic、コンパイル時の型を持つこれらのオペランドの実行時の型を使用して実行時に以下に示す解決が行わdynamicします。In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

乗算演算子Multiplication operator

フォームの操作のx * y、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x * y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの乗算演算子は、以下に示します。The predefined multiplication operators are listed below. すべての演算子の積が計算xyします。The operators all compute the product of x and y.

  • 整数の乗算します。Integer multiplication:

    int operator *(int x, int y);
    uint operator *(uint x, uint y);
    long operator *(long x, long y);
    ulong operator *(ulong x, ulong y);
    

    checked製品が結果の型の範囲外の場合は、コンテキスト、System.OverflowExceptionがスローされます。In a checked context, if the product is outside the range of the result type, a System.OverflowException is thrown. uncheckedコンテキスト、オーバーフローが報告されず、結果型の範囲外有意の上位ビットは破棄されます。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • 浮動小数点の乗算します。Floating-point multiplication:

    float operator *(float x, float y);
    double operator *(double x, double y);
    

    製品は、IEEE 754 の演算の規則に従って計算されます。The product is computed according to the rules of IEEE 754 arithmetic. 次の表では、有限値が 0 以外の場合の可能なすべての組み合わせ、ゼロ、無限大および NaN の結果を示します。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 表に、xyは正の有限値。In the table, x and y are positive finite values. z 結果は、x * yします。z is the result of x * y. 変換先の型に対して、結果が大きすぎる場合z無限大です。If the result is too large for the destination type, z is infinity. 変換先の型の結果が小さすぎる場合zは 0 です。If the result is too small for the destination type, z is zero.

    + y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    +x+x + z+z ~ z-z +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    -x-x ~ z-z + z+z -0-0 +0+0 -inf-inf +inf+inf NaNNaN
    +0+0 +0+0 -0-0 +0+0 -0-0 NaNNaN NaNNaN NaNNaN
    -0-0 -0-0 +0+0 -0-0 +0+0 NaNNaN NaNNaN NaNNaN
    +inf+inf +inf+inf -inf-inf NaNNaN NaNNaN +inf+inf -inf-inf NaNNaN
    -inf-inf -inf-inf +inf+inf NaNNaN NaNNaN -inf-inf +inf+inf NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • 10 進数の乗算します。Decimal multiplication:

    decimal operator *(decimal x, decimal y);
    

    結果の値が大きすぎてで表すかどうか、decimal形式、System.OverflowExceptionがスローされます。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 結果値はで表現するには小さすぎるかどうか、decimal形式、結果は 0 です。If the result value is too small to represent in the decimal format, the result is zero. 丸めを行う前に、結果の小数点以下桁数は、2 つのオペランドのスケールの合計です。The scale of the result, before any rounding, is the sum of the scales of the two operands.

    10 進数の乗算は型の乗算演算子を使用すると、System.Decimalします。Decimal multiplication is equivalent to using the multiplication operator of type System.Decimal.

除算演算子Division operator

フォームの操作のx / y、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x / y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの除算演算子は、以下に示します。The predefined division operators are listed below. すべての演算子の商を計算するxyします。The operators all compute the quotient of x and y.

  • 整数除算します。Integer division:

    int operator /(int x, int y);
    uint operator /(uint x, uint y);
    long operator /(long x, long y);
    ulong operator /(ulong x, ulong y);
    

    右側のオペランドの値が 0 の場合、System.DivideByZeroExceptionがスローされます。If the value of the right operand is zero, a System.DivideByZeroException is thrown.

    除算では、0 方向に結果を丸めます。The division rounds the result towards zero. したがって、結果の絶対値が 2 つのオペランドの商の絶対値と等しいまたはそれより小さい最大整数です。Thus the absolute value of the result is the largest possible integer that is less than or equal to the absolute value of the quotient of the two operands. 結果は、2 つのオペランドが同じ符号がある、または記号の反対側の 2 つのオペランドが負の場合は 0 または正の値。The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs.

    左側のオペランドが表現可能な最小の場合intまたはlong値と右辺オペランドは-1オーバーフローが発生します。If the left operand is the smallest representable int or long value and the right operand is -1, an overflow occurs. checkedコンテキスト、これにより、 System.ArithmeticException (またはそのサブクラス) がスローされます。In a checked context, this causes a System.ArithmeticException (or a subclass thereof) to be thrown. unchecked実装で定義されたかどうかは、そのコンテキストをSystem.ArithmeticException(またはそのサブクラス) がスローされますまたは結果の中、左側のオペランドの値に、オーバーフローが報告されません。In an unchecked context, it is implementation-defined as to whether a System.ArithmeticException (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.

  • 浮動小数点除算します。Floating-point division:

    float operator /(float x, float y);
    double operator /(double x, double y);
    

    商は、IEEE 754 の演算の規則に従って計算されます。The quotient is computed according to the rules of IEEE 754 arithmetic. 次の表では、有限値が 0 以外の場合の可能なすべての組み合わせ、ゼロ、無限大および NaN の結果を示します。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 表に、xyは正の有限値。In the table, x and y are positive finite values. z 結果は、x / yします。z is the result of x / y. 変換先の型に対して、結果が大きすぎる場合z無限大です。If the result is too large for the destination type, z is infinity. 変換先の型の結果が小さすぎる場合zは 0 です。If the result is too small for the destination type, z is zero.

    + y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    +x+x + z+z ~ z-z +inf+inf -inf-inf +0+0 -0-0 NaNNaN
    -x-x ~ z-z + z+z -inf-inf +inf+inf -0-0 +0+0 NaNNaN
    +0+0 +0+0 -0-0 NaNNaN NaNNaN +0+0 -0-0 NaNNaN
    -0-0 -0-0 +0+0 NaNNaN NaNNaN -0-0 +0+0 NaNNaN
    +inf+inf +inf+inf -inf-inf +inf+inf -inf-inf NaNNaN NaNNaN NaNNaN
    -inf-inf -inf-inf +inf+inf -inf-inf +inf+inf NaNNaN NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • 小数除算します。Decimal division:

    decimal operator /(decimal x, decimal y);
    

    右側のオペランドの値が 0 の場合、System.DivideByZeroExceptionがスローされます。If the value of the right operand is zero, a System.DivideByZeroException is thrown. 結果の値が大きすぎてで表すかどうか、decimal形式、System.OverflowExceptionがスローされます。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 結果値はで表現するには小さすぎるかどうか、decimal形式、結果は 0 です。If the result value is too small to represent in the decimal format, the result is zero. 結果の小数点以下桁数と等しい、結果を保持する最小のスケール、実際の計算結果を 10 進値を表現できる最も近い。The scale of the result is the smallest scale that will preserve a result equal to the nearest representable decimal value to the true mathematical result.

    10 進数の除算は型の除算演算子を使用すると、System.Decimalします。Decimal division is equivalent to using the division operator of type System.Decimal.

剰余演算子Remainder operator

フォームの操作のx % y、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x % y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの剰余演算子は、以下に示します。The predefined remainder operators are listed below. すべての演算子の間での除算の剰余を計算xyします。The operators all compute the remainder of the division between x and y.

  • 整数の剰余。Integer remainder:

    int operator %(int x, int y);
    uint operator %(uint x, uint y);
    long operator %(long x, long y);
    ulong operator %(ulong x, ulong y);
    

    結果x % yによって値が生成されるx - (x / y) * yします。The result of x % y is the value produced by x - (x / y) * y. 場合y0 の場合は、System.DivideByZeroExceptionがスローされます。If y is zero, a System.DivideByZeroException is thrown.

    左側のオペランドが最も場合intまたはlong値と右辺オペランドは-1System.OverflowExceptionがスローされます。If the left operand is the smallest int or long value and the right operand is -1, a System.OverflowException is thrown. ない場合はx % y例外をスロー場所x / yは例外をスローできません。In no case does x % y throw an exception where x / y would not throw an exception.

  • 浮動小数点の剰余。Floating-point remainder:

    float operator %(float x, float y);
    double operator %(double x, double y);
    

    次の表では、有限値が 0 以外の場合の可能なすべての組み合わせ、ゼロ、無限大および NaN の結果を示します。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 表に、xyは正の有限値。In the table, x and y are positive finite values. z 結果は、x % yを計算してx - n * yここで、nに等しいまたはそれより小さい最大整数をx / yします。z is the result of x % y and is computed as x - n * y, where n is the largest possible integer that is less than or equal to x / y. 残りの部分をコンピューティングするのには、このメソッドは整数オペランドで使用される類似していますが、IEEE 754 の定義とは異なります (これでnに最も近い整数は、 x / y)。This method of computing the remainder is analogous to that used for integer operands, but differs from the IEEE 754 definition (in which n is the integer closest to x / y).

    + y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    +x+x + z+z + z+z NaNNaN NaNNaN xx xx NaNNaN
    -x-x ~ z-z ~ z-z NaNNaN NaNNaN -x-x -x-x NaNNaN
    +0+0 +0+0 +0+0 NaNNaN NaNNaN +0+0 +0+0 NaNNaN
    -0-0 -0-0 -0-0 NaNNaN NaNNaN -0-0 -0-0 NaNNaN
    +inf+inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
    -inf-inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • 10 進数の剰余。Decimal remainder:

    decimal operator %(decimal x, decimal y);
    

    右側のオペランドの値が 0 の場合、System.DivideByZeroExceptionがスローされます。If the value of the right operand is zero, a System.DivideByZeroException is thrown. 丸めを行う前に、結果の小数点以下桁数は 2 つのオペランドの規模の大きいと、結果の符号は、0 以外の場合はいるのと同じxします。The scale of the result, before any rounding, is the larger of the scales of the two operands, and the sign of the result, if non-zero, is the same as that of x.

    10 進数の残りの部分は型の剰余演算子を使用するとSystem.Decimalします。Decimal remainder is equivalent to using the remainder operator of type System.Decimal.

加算演算子Addition operator

フォームの操作のx + y、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x + y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの加算演算子は、以下に示します。The predefined addition operators are listed below. 数値型と列挙型の場合は、定義済みの加算演算子は、2 つのオペランドの合計を計算します。For numeric and enumeration types, the predefined addition operators compute the sum of the two operands. 1 つまたは両方のオペランドが文字列型、定義済みの加算演算子はオペランドの文字列表現を連結します。When one or both operands are of type string, the predefined addition operators concatenate the string representation of the operands.

  • 整数の加算:Integer addition:

    int operator +(int x, int y);
    uint operator +(uint x, uint y);
    long operator +(long x, long y);
    ulong operator +(ulong x, ulong y);
    

    checkedコンテキスト、合計が、結果の型の範囲外の場合、System.OverflowExceptionがスローされます。In a checked context, if the sum is outside the range of the result type, a System.OverflowException is thrown. uncheckedコンテキスト、オーバーフローが報告されず、結果型の範囲外有意の上位ビットは破棄されます。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • 浮動小数点加算します。Floating-point addition:

    float operator +(float x, float y);
    double operator +(double x, double y);
    

    合計は、IEEE 754 の演算の規則に従って計算されます。The sum is computed according to the rules of IEEE 754 arithmetic. 次の表では、有限値が 0 以外の場合の可能なすべての組み合わせ、ゼロ、無限大および NaN の結果を示します。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 表に、xyは 0 以外の値の有限値とzの結果は、x + yします。In the table, x and y are nonzero finite values, and z is the result of x + y. 場合xy絶対値が同じ記号、方向が逆zは正の 0 になります。If x and y have the same magnitude but opposite signs, z is positive zero. 場合x + yが大きすぎて、変換先の型で表すz、無限大と同じ符号でx + yします。If x + y is too large to represent in the destination type, z is an infinity with the same sign as x + y.

    Yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    xx zz xx xx +inf+inf -inf-inf NaNNaN
    +0+0 Yy +0+0 +0+0 +inf+inf -inf-inf NaNNaN
    -0-0 Yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    +inf+inf +inf+inf +inf+inf +inf+inf +inf+inf NaNNaN NaNNaN
    -inf-inf -inf-inf -inf-inf -inf-inf NaNNaN -inf-inf NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • 10 進数の追加:Decimal addition:

    decimal operator +(decimal x, decimal y);
    

    結果の値が大きすぎてで表すかどうか、decimal形式、System.OverflowExceptionがスローされます。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 丸めを行う前に、結果の小数点以下桁数は 2 つのオペランドのスケールのうち、大きい方です。The scale of the result, before any rounding, is the larger of the scales of the two operands.

    10 進数の加算は型の加算演算子を使用すると、System.Decimalします。Decimal addition is equivalent to using the addition operator of type System.Decimal.

  • 列挙型の加算します。Enumeration addition. すべての列挙型を暗黙的に、次の定義済みの演算子、提供、E列挙型とUの基になる型は、 E:Every enumeration type implicitly provides the following predefined operators, where E is the enum type, and U is the underlying type of E:

    E operator +(E x, U y);
    E operator +(U x, E y);
    

    実行時にこれらの演算子が正確に評価されます(E)((U)x + (U)y)します。At run-time these operators are evaluated exactly as (E)((U)x + (U)y).

  • 文字列の連結。String concatenation:

    string operator +(string x, string y);
    string operator +(string x, object y);
    string operator +(object x, string y);
    

    これらのオーバー ロードのバイナリの+演算子が文字列の連結を実行します。These overloads of the binary + operator perform string concatenation. 文字列の連結のオペランドは場合null、空の文字列に置き換えられます。If an operand of string concatenation is null, an empty string is substituted. 仮想を呼び出すことによって、任意の文字列以外の引数を文字列形式に変換がそれ以外の場合、ToString型から継承されたメソッドobjectします。Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. 場合ToString返しますnull、空の文字列に置き換えられます。If ToString returns null, an empty string is substituted.

    using System;
    
    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
        }
    }
    

    文字列連結演算子の結果は、左オペランドと右辺オペランドの文字が続くの文字で構成される文字列です。 文字列連結演算子が返すことはありません、null値。 ASystem.OutOfMemoryException結果の文字列を割り当てることができる十分なメモリがない場合にスローされる可能性があります。A System.OutOfMemoryException may be thrown if there is not enough memory available to allocate the resulting string.

  • デリゲートの組み合わせ。Delegate combination. すべてのデリゲート型が暗黙的に次の定義済みの演算子を提供します、Dはデリゲート型です。Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

    D operator +(D x, D y);
    

    バイナリ+演算子は、両方のオペランドがいくつかのデリゲート型の場合、デリゲートの組み合わせを実行Dします。The binary + operator performs delegate combination when both operands are of some delegate type D. (この場合、オペランドに異なるデリゲート型では、バインド時のエラーが発生します。)最初のオペランドが場合null、操作の結果は、2 番目のオペランドの値 (である場合でもnull)。(If the operands have different delegate types, a binding-time error occurs.) If the first operand is null, the result of the operation is the value of the second operand (even if that is also null). それ以外の場合、2 番目のオペランドが場合null操作の結果は最初のオペランドの値。Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. それ以外の場合、操作の結果は、新しいデリゲート インスタンスが、呼び出される、最初のオペランドを呼び出すし、2 番目のオペランドを呼び出します。Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand. デリゲートの組み合わせの例については、次を参照してください。減算演算子デリゲート呼び出しします。For examples of delegate combination, see Subtraction operator and Delegate invocation. System.Delegate 、デリゲート型ではないoperator +用に定義されていません。Since System.Delegate is not a delegate type, operator + is not defined for it.

減算演算子Subtraction operator

フォームの操作のx - y、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x - y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの減算演算子は、以下に示します。The predefined subtraction operators are listed below. すべての減算演算子yからxします。The operators all subtract y from x.

  • 整数の減算:Integer subtraction:

    int operator -(int x, int y);
    uint operator -(uint x, uint y);
    long operator -(long x, long y);
    ulong operator -(ulong x, ulong y);
    

    checkedコンテキスト、違いが結果の型の範囲外の場合、System.OverflowExceptionがスローされます。In a checked context, if the difference is outside the range of the result type, a System.OverflowException is thrown. uncheckedコンテキスト、オーバーフローが報告されず、結果型の範囲外有意の上位ビットは破棄されます。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • 浮動小数点の減算:Floating-point subtraction:

    float operator -(float x, float y);
    double operator -(double x, double y);
    

    違いは、IEEE 754 の演算の規則に従って計算されます。The difference is computed according to the rules of IEEE 754 arithmetic. 次の表では、0 以外の値の有限値の可能なすべての組み合わせ、ゼロ、無限大および Nan の結果を示します。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaNs. 表に、xyは 0 以外の値の有限値とzの結果は、x - yします。In the table, x and y are nonzero finite values, and z is the result of x - y. 場合xyが等しいか、zは正の 0 になります。If x and y are equal, z is positive zero. 場合x - yが大きすぎて、変換先の型で表すz、無限大と同じ符号でx - yします。If x - y is too large to represent in the destination type, z is an infinity with the same sign as x - y.

    Yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
    xx zz xx xx -inf-inf +inf+inf NaNNaN
    +0+0 -y-y +0+0 +0+0 -inf-inf +inf+inf NaNNaN
    -0-0 -y-y -0-0 +0+0 -inf-inf +inf+inf NaNNaN
    +inf+inf +inf+inf +inf+inf +inf+inf NaNNaN +inf+inf NaNNaN
    -inf-inf -inf-inf -inf-inf -inf-inf -inf-inf NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • 10 進数の減算:Decimal subtraction:

    decimal operator -(decimal x, decimal y);
    

    結果の値が大きすぎてで表すかどうか、decimal形式、System.OverflowExceptionがスローされます。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 丸めを行う前に、結果の小数点以下桁数は 2 つのオペランドのスケールのうち、大きい方です。The scale of the result, before any rounding, is the larger of the scales of the two operands.

    10 進数の減算は、型の減算演算子を使用するとSystem.Decimalします。Decimal subtraction is equivalent to using the subtraction operator of type System.Decimal.

  • 列挙型の減算します。Enumeration subtraction. すべての列挙型が暗黙的に次の定義済みの演算子を提供、E列挙型とUの基になる型は、 E:Every enumeration type implicitly provides the following predefined operator, where E is the enum type, and U is the underlying type of E:

    U operator -(E x, E y);
    

    この演算子の評価とまったく同じ(U)((U)x - (U)y)します。This operator is evaluated exactly as (U)((U)x - (U)y). つまりの序数値の差の計算演算子xy、列挙体の基になる型であり、結果の型。In other words, the operator computes the difference between the ordinal values of x and y, and the type of the result is the underlying type of the enumeration.

    E operator -(E x, U y);
    

    この演算子の評価とまったく同じ(E)((U)x - y)します。This operator is evaluated exactly as (E)((U)x - y). つまり、演算子は、減算、列挙体の基になる型の値列挙体の値として生成します。In other words, the operator subtracts a value from the underlying type of the enumeration, yielding a value of the enumeration.

  • デリゲートの削除。Delegate removal. すべてのデリゲート型が暗黙的に次の定義済みの演算子を提供します、Dはデリゲート型です。Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

    D operator -(D x, D y);
    

    バイナリ-演算子は、両方のオペランドがいくつかのデリゲート型の場合、デリゲートの削除を実行Dします。The binary - operator performs delegate removal when both operands are of some delegate type D. オペランドに異なるデリゲート型がある場合、バインド時のエラーが発生します。If the operands have different delegate types, a binding-time error occurs. 最初のオペランドが場合null、操作の結果はnullします。If the first operand is null, the result of the operation is null. それ以外の場合、2 番目のオペランドが場合null操作の結果は最初のオペランドの値。Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. それ以外の場合、両方のオペランドが呼び出しリストを表す (デリゲートの宣言) 1 つまたは複数のエントリと、結果はから削除された、2 番目のオペランドのエントリで、最初のオペランドの一覧から成る新しい呼び出しリスト最初の連続するサブリストは、2 番目のオペランドの一覧を提供です。Otherwise, both operands represent invocation lists (Delegate declarations) having one or more entries, and the result is a new invocation list consisting of the first operand's list with the second operand's entries removed from it, provided the second operand's list is a proper contiguous sublist of the first's. (デリゲートの等値演算子とサブリスト、対応するエントリが比較されます (デリゲート等値演算子).)それ以外の場合、結果は、左側のオペランドの値です。(To determine sublist equality, corresponding entries are compared as for the delegate equality operator (Delegate equality operators).) Otherwise, the result is the value of the left operand. プロセスのどちらのオペランドのリストが変更されます。Neither of the operands' lists is changed in the process. 2 番目のオペランドの一覧には、最初のオペランドのリスト内の連続したエントリの複数のサブリストが一致すると、連続するエントリの右端の一致するサブリストは削除されます。If the second operand's list matches multiple sublists of contiguous entries in the first operand's list, the right-most matching sublist of contiguous entries is removed. 削除の結果、空のリストになる場合、結果はnullします。If removal results in an empty list, the result is null. 例:For example:

    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 cd3 = cd1 + cd2 + cd2 + cd1;   // M1 + M2 + M2 + M1
            cd3 -= cd1;                      // => M1 + M2 + M2
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd1 + cd2;                // => M2 + M1
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd2 + cd2;                // => M1 + M1
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd2 + cd1;                // => M1 + M2
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd1 + cd1;                // => M1 + M2 + M2 + M1
        }
    }
    

シフト演算子Shift operators

<<>>演算子を使用して、ビット シフト演算を実行します。The << and >> operators are used to perform bit shifting operations.

shift_expression
    : additive_expression
    | shift_expression '<<' additive_expression
    | shift_expression right_shift additive_expression
    ;

オペランドの場合、 shift_expressionコンパイル時の型を持つdynamic、式を動的にバインドし、(動的バインド)。If an operand of a shift_expression has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). この場合、式のコンパイル時の型はdynamic、コンパイル時の型を持つこれらのオペランドの実行時の型を使用して実行時に以下に示す解決が行わdynamicします。In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

フォームの操作のx << countまたはx >> count、二項演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x << count or x >> count, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

最初のオペランドの型では、クラスまたは構造体の演算子の宣言を含むをある必要が常にオーバー ロードされた shift 演算子を宣言するときにあり、2 番目のオペランドの型は常にありますintします。When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration, and the type of the second operand must always be int.

定義済みのシフト演算子は、以下に示します。The predefined shift operators are listed below.

  • 左にシフトします。Shift left:

    int operator <<(int x, int count);
    uint operator <<(uint x, int count);
    long operator <<(long x, int count);
    ulong operator <<(ulong x, int count);
    

    <<演算子シフトxビット数だけ左が以下に示すように計算します。The << operator shifts x left by a number of bits computed as described below.

    結果型の範囲外の上位ビットxが破棄されるので、残りのビットが左にシフトされ、下位の空のビット位置が 0 に設定します。The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero.

  • 右シフトします。Shift right:

    int operator >>(int x, int count);
    uint operator >>(uint x, int count);
    long operator >>(long x, int count);
    ulong operator >>(ulong x, int count);
    

    >>演算子シフトxビット数だけ右が以下に示すように計算します。The >> operator shifts x right by a number of bits computed as described below.

    ときにxの種類はintまたはlongの下位ビットxは破棄されるので、残りのビットが右にシフトし、空の上位ビット位置は場合は 0 に設定されますx負でないと設定は、1 つの場合にxが負の値。When x is of type int or long, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative.

    ときにxの種類はuintまたはulongの下位ビットxが破棄されるので、残りのビットは右にシフトして、空の上位ビット位置が 0 に設定します。When x is of type uint or ulong, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.

定義済みの演算子のとおりにシフトするビット数が計算されます。For the predefined operators, the number of bits to shift is computed as follows:

  • 場合の種類xintまたはuintの下位 5 ビットで、シフト数を指定countします。When the type of x is int or uint, the shift count is given by the low-order five bits of count. つまり、シフト数がから計算されたcount & 0x1Fします。In other words, the shift count is computed from count & 0x1F.
  • 場合の種類xlongまたはulongの下位 6 ビットで、シフト数を指定countします。When the type of x is long or ulong, the shift count is given by the low-order six bits of count. つまり、シフト数がから計算されたcount & 0x3Fします。In other words, the shift count is computed from count & 0x3F.

シフト演算子は単の値を返す結果として得られる、シフト数が 0 の場合は、xします。If the resulting shift count is zero, the shift operators simply return the value of x.

オーバーフローが発生してで同じ結果を生成しないのシフト演算をcheckeduncheckedコンテキスト。Shift operations never cause overflows and produce the same results in checked and unchecked contexts.

ときの左オペランド、>>演算子が符号付き整数型は、算術右シフトのオペランドの最上位ビット (符号ビット) の値を反映する、空の上位ビット位置を実行します。When the left operand of the >> operator is of a signed integral type, the operator performs an arithmetic shift right wherein the value of the most significant bit (the sign bit) of the operand is propagated to the high-order empty bit positions. ときの左オペランド、>>演算子が符号なし整数型は、演算子、論理右シフトが行われ、空の上位ビット位置には常に 0 が設定されます。When the left operand of the >> operator is of an unsigned integral type, the operator performs a logical shift right wherein high-order empty bit positions are always set to zero. オペランドの型から推論の反対側の操作を実行するには、明示的なキャストを使用していることができます。To perform the opposite operation of that inferred from the operand type, explicit casts can be used. たとえば場合、x型の変数は、 int、操作unchecked((int)((uint)x >> y))論理の右シフトを実行します。xします。For example, if x is a variable of type int, the operation unchecked((int)((uint)x >> y)) performs a logical shift right of x.

関係演算子と型検査演算子Relational and type-testing operators

==!=<><=>=isas演算子は、リレーショナルと型検査演算子と呼ばれます。The ==, !=, <, >, <=, >=, is and as operators are called the relational and type-testing operators.

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 'as' type
    ;

equality_expression
    : relational_expression
    | equality_expression '==' relational_expression
    | equality_expression '!=' relational_expression
    ;

is演算子については、「 、演算子は、as演算子については、「演算子としてします。The is operator is described in The is operator and the as operator is described in The as operator.

==!=<><=>=演算子は比較演算子します。The ==, !=, <, >, <= and >= operators are comparison operators.

比較演算子のオペランドがコンパイル時の型を持つかどうかdynamic、式を動的にバインドし、(動的バインド)。If an operand of a comparison operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). この場合、式のコンパイル時の型はdynamic、コンパイル時の型を持つこれらのオペランドの実行時の型を使用して実行時に以下に示す解決が行わdynamicします。In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

フォームの操作のx op yここで、 op比較演算子をオーバー ロードの解決 (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x op y, where op is a comparison operator, overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの比較演算子は、次のセクションで説明します。The predefined comparison operators are described in the following sections. すべての定義済みの比較演算子は、型の結果を返すbool次の表で説明するようにします。All predefined comparison operators return a result of type bool, as described in the following table.

操作Operation 結果Result
x == y true 場合xと等しいyfalseそれ以外の場合true if x is equal to y, false otherwise
x != y true 場合xが等しくないyfalseそれ以外の場合true if x is not equal to y, false otherwise
x < y true 場合xがより小さいyfalseそれ以外の場合true if x is less than y, false otherwise
x > y true 場合xがより大きいyfalseそれ以外の場合true if x is greater than y, false otherwise
x <= y true 場合xに等しいまたはそれよりも小さいyfalseそれ以外の場合true if x is less than or equal to y, false otherwise
x >= y true 場合xがより大きいまたは等しいyfalseそれ以外の場合true if x is greater than or equal to y, false otherwise

整数の比較演算子Integer comparison operators

定義済みの整数の比較演算子は次のとおりです。The predefined integer comparison operators are:

bool operator ==(int x, int y);
bool operator ==(uint x, uint 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 !=(long x, long y);
bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);
bool operator <(uint x, uint 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 >(long x, long y);
bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);
bool operator <=(uint x, uint 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 >=(long x, long y);
bool operator >=(ulong x, ulong y);

返します、2 つの整数オペランドの数値を比較これらの各演算子をbool、特定の関係は、かどうかを示す値trueまたはfalseします。Each of these operators compares the numeric values of the two integer operands and returns a bool value that indicates whether the particular relation is true or false.

浮動小数点の比較演算子Floating-point comparison operators

定義済みの浮動小数点数の比較演算子は次のとおりです。The predefined floating-point comparison operators are:

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);

演算子は、IEEE 754 標準の規則に従ってオペランドを比較します。The operators compare the operands according to the rules of the IEEE 754 standard:

  • 結果は、いずれかのオペランドが NaN の場合は、falseを除くすべての演算子の!=、結果が対象のtrueします。If either operand is NaN, the result is false for all operators except !=, for which the result is true. 任意の 2 つのオペランドのx != yと同じ結果を常に生成!(x == y)します。For any two operands, x != y always produces the same result as !(x == y). ただし、1 つまたは両方のオペランドが NaN の場合が場合、 <><=、および>=演算子は、反対側の演算子の論理否定演算と同じ結果を生成しません。However, when one or both operands are NaN, the <, >, <=, and >= operators do not produce the same results as the logical negation of the opposite operator. たとえば、いずれかのxyが NaN の場合、x < yfalse!(x >= y)trueFor example, if either of x and y is NaN, then x < y is false, but !(x >= y) is true.

  • 演算子が順序に関して 2 つの浮動小数点のオペランドの値を比較してどちらのオペランドが NaN の場合は、When neither operand is NaN, the operators compare the values of the two floating-point operands with respect to the ordering

    -inf < -max < ... < -min < -0.0 == +0.0 < +min < ... < +max < +inf
    

    場所minmaxは、最小および最大の正の有限値を指定した浮動小数点形式で表すことができます。where min and max are the smallest and largest positive finite values that can be represented in the given floating-point format. この順序付けの注目すべき効果は次のとおりです。Notable effects of this ordering are:

    • 負と正のゼロは等しいと見なされます。Negative and positive zeros are considered equal.
    • 負の無限大は小さい他のすべての値よりも、もう 1 つの負の無限大とは等しいと見なされます。A negative infinity is considered less than all other values, but equal to another negative infinity.
    • 正の無限大は、その他のすべての値より大きい値がもう 1 つの正の無限大に等しいと見なされます。A positive infinity is considered greater than all other values, but equal to another positive infinity.

10 進数の比較演算子Decimal comparison operators

定義済みの 10 進数の比較演算子は次のとおりです。The predefined decimal comparison operators are:

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します。Each of these operators compares the numeric values of the two decimal operands and returns a bool value that indicates whether the particular relation is true or false. 各 10 進数の比較では、対応するリレーショナルまたは型の等値演算子を使用するとSystem.Decimalします。Each decimal comparison is equivalent to using the corresponding relational or equality operator of type System.Decimal.

ブール等価演算子Boolean equality operators

定義済みのブール値の等値演算子は次のとおりです。The predefined boolean equality operators are:

bool operator ==(bool x, bool y);
bool operator !=(bool x, bool y);

結果==true両方xytrue両方またはxyfalseします。The result of == is true if both x and y are true or if both x and y are false. それ以外の場合、結果は false です。Otherwise, the result is false.

結果!=false両方xytrue両方またはxyfalseします。The result of != is false if both x and y are true or if both x and y are false. それ以外の場合、結果は true です。Otherwise, the result is true. 型のオペランドが場合bool!=演算子と同じ結果を生成する、^演算子。When the operands are of type bool, the != operator produces the same result as the ^ operator.

列挙体の比較演算子Enumeration comparison operators

すべての列挙型には、次の定義済みの比較演算子が暗黙的に用意されています。Every enumeration type implicitly provides the following predefined comparison operators:

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ここで、xy列挙型の式はE基になる型U、およびop比較演算子の 1 つと同じでは正確に評価する((U)x) op ((U)y)します。The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the comparison operators, is exactly the same as evaluating ((U)x) op ((U)y). つまり、列挙型の比較演算子は、単に 2 つのオペランドの基になる整数値を比較します。In other words, the enumeration type comparison operators simply compare the underlying integral values of the two operands.

参照型の等値演算子Reference type equality operators

定義済みの参照型の等値演算子は次のとおりです。The predefined reference type equality operators are:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

演算子は、2 つの参照が等値演算子または非等値比較の結果を返します。The operators return the result of comparing the two references for equality or non-equality.

定義済みの参照型の等値演算子は、型のオペランドを受け入れるためobject、適用可能な宣言しないすべての種類に適用されるoperator ==operator !=メンバー。Since the predefined reference type equality operators accept operands of type object, they apply to all types that do not declare applicable operator == and operator != members. 逆に、任意の該当するユーザー定義の等値演算子には、定義済みの参照型の等値演算子効果的に非表示にします。Conversely, any applicable user-defined equality operators effectively hide the predefined reference type equality operators.

定義済みの参照型の等値演算子では、次のいずれかが必要です。The predefined reference type equality operators require one of the following:

  • 両方のオペランドがある既知の型の値をreference_typeまたはリテラルnullします。Both operands are a value of a type known to be a reference_type or the literal null. さらに、明示的な参照変換 (明示的な参照変換) のいずれかのオペランドの型からもう一方のオペランドの型に存在します。Furthermore, an explicit reference conversion (Explicit reference conversions) exists from the type of either operand to the type of the other operand.
  • 1 つのオペランド型の値は、T場所Tは、 type_parameterもう一方のオペランドは、リテラルとnullします。One operand is a value of type T where T is a type_parameter and the other operand is the literal null. さらにT値型の制約はありません。Furthermore T does not have the value type constraint.

これらの条件のいずれかに該当する場合を除き、バインド時のエラーが発生します。Unless one of these conditions are true, a binding-time error occurs. これらのルールの主な特性は次のとおりです。Notable implications of these rules are:

  • 別のバインド時に認識されている 2 つの参照を比較する定義済みの参照型の等値演算子を使用すると、バインド時エラーになります。It is a binding-time error to use the predefined reference type equality operators to compare two references that are known to be different at binding-time. たとえば、オペランドのバインド時の型は、2 つのクラス型AB、どちらの場合とABの 2 つのオペランドが同じオブジェクトを参照することはできませんし、もう一方の派生です。For example, if the binding-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. そのため、操作は、バインド時のエラーと見なされます。Thus, the operation is considered a binding-time error.
  • 定義済みの参照型の等値演算子は値と比較する型のオペランドを許可しない操作を行います。The predefined reference type equality operators do not permit value type operands to be compared. そのため、構造体型で独自の等値演算子を宣言しない限り、その構造体の型の値を比較することはできません。Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type.
  • 定義済みの参照型の等値演算子には、オペランドにボックス化操作が発生しません。The predefined reference type equality operators never cause boxing operations to occur for their operands. 新しく割り当てられたボックス化されたインスタンスへの参照は、必然的に他のすべての参照と異なっているために、このようなボックス化操作を実行しても意味があります。It would be meaningless to perform such boxing operations, since references to the newly allocated boxed instances would necessarily differ from all other references.
  • 場合、型パラメーターの型のオペランドTと比較するnullの実行時の型とT値型である比較の結果はfalseします。If an operand of a type parameter type T is compared to null, and the run-time type of T is a value type, the result of the comparison is false.

次の例は、制約のない型パラメーターの型の引数がかどうかを確認します。nullします。The following example checks whether an argument of an unconstrained type parameter type is null.

class C<T>
{
    void F(T x) {
        if (x == null) throw new ArgumentNullException();
        ...
    }
}

x == nullコンストラクトは許可されている場合でもT値の型を表すことができ、結果は、単に定義falseときTは値型です。The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type.

フォームの操作のx == yまたはx != y任意の該当する場合は、operator ==またはoperator !=存在する場合、演算子のオーバー ロードの解決 (二項演算子のオーバー ロードの解決) ルールを選択します。定義済みの参照型の等値演算子ではなく演算子です。For an operation of the form x == y or x != y, if any applicable operator == or operator != exists, the operator overload resolution (Binary operator overload resolution) rules will select that operator instead of the predefined reference type equality operator. ただし、いずれかまたは両方のオペランドを型を明示的にキャストすることによって、定義済みの参照型の等値演算子を選択することは常にobjectします。However, it is always possible to select the predefined reference type equality operator by explicitly casting one or both of the operands to type object. 例では、The example

using System;

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);
    }
}

この例では、次のように出力されます。produces the output

True
False
False
False

st変数を指す 2 つの異なるstring同じ文字を含むインスタンス。The s and t variables refer to two distinct string instances containing the same characters. 最初の比較出力Trueため、定義済みの文字列の等値演算子 (文字列等値演算子) が選択されているは、両方のオペランド型の場合stringThe first comparison outputs True because the predefined string equality operator (String equality operators) is selected when both operands are of type string. 残りの比較をすべて出力False1 つまたは両方のオペランドの型の場合、定義済みの参照型の等値演算子が選択されているため、objectします。The remaining comparisons all output False because the predefined reference type equality operator is selected when one or both of the operands are of type object.

前述の手法が意味のある値型ではないことに注意してください。Note that the above technique is not meaningful for value types. 例では、The example

class Test
{
    static void Main() {
        int i = 123;
        int j = 123;
        System.Console.WriteLine((object)i == (object)j);
    }
}

出力Falseキャストの 2 つのインスタンスへの参照を作成するためのボックス化int値。outputs False because the casts create references to two separate instances of boxed int values.

文字列の等値演算子String equality operators

定義済みの文字列の等値演算子は次のとおりです。The predefined string equality operators are:

bool operator ==(string x, string y);
bool operator !=(string x, string y);

2 つstring値が等しいと見なされる、次のいずれかが true の場合。Two string values are considered equal when one of the following is true:

  • 両方の値がnullします。Both values are null.
  • 両方の値に各文字の位置と同じ長さと同じ文字を含む文字列のインスタンスに null 参照です。Both values are non-null references to string instances that have identical lengths and identical characters in each character position.

文字列の等値演算子は、文字列の参照ではなく、文字列値を比較します。The string equality operators compare string values rather than string references. 2 つの別個の文字列のインスタンスに正確な同じ一連の文字が含まれている場合は、文字列の値が等しいかが、参照は異なります。When two separate string instances contain the exact same sequence of characters, the values of the strings are equal, but the references are different. 」の説明に従って参照型の等値演算子参照型の等値演算子は、文字列値ではなく文字列の参照を比較するために使用できます。As described in Reference type equality operators, the reference type equality operators can be used to compare string references instead of string values.

デリゲートの等値演算子Delegate equality operators

すべてのデリゲート型には、次の定義済みの比較演算子が暗黙的に用意されています。Every delegate type implicitly provides the following predefined comparison operators:

bool operator ==(System.Delegate x, System.Delegate y);
bool operator !=(System.Delegate x, System.Delegate y);

2 つのデリゲート インスタンスが等しいとおり。Two delegate instances are considered equal as follows:

  • デリゲートのインスタンスのいずれかの場合null、両方とも場合にのみが等しいnullします。If either of the delegate instances is null, they are equal if and only if both are null.
  • デリゲートがある別の実行時の型と等しいもことはありません。If the delegates have different run-time type they are never equal.
  • 呼び出しリストが両方のデリゲート インスタンスがあるかどうか (デリゲートの宣言)、場合にだけ、それぞれの呼び出しリストが同じ長さと 1 つの呼び出しリスト内の各エントリは (下記を参照) のように、それらのインスタンスが等しいその他の呼び出しリスト内の順序で対応するエントリ。If both of the delegate instances have an invocation list (Delegate declarations), those instances are equal if and only if their invocation lists are the same length, and each entry in one's invocation list is equal (as defined below) to the corresponding entry, in order, in the other's invocation list.

次の規則は、呼び出しリストのエントリが等しいかどうかを制御します。The following rules govern the equality of invocation list entries:

  • 2 つの呼び出しリストのエントリが両方が同じ静的に参照している場合、メソッド、エントリは等しくなります。If two invocation list entries both refer to the same static method then the entries are equal.
  • 2 つの呼び出しリストのエントリが両方が同じターゲット オブジェクトで同じ非静的メソッドを参照してください (参照の等値演算子で定義) された場合、エントリは等しくなります。If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
  • 呼び出しリストのエントリが意味的に同一の評価から生成されたanonymous_method_expressions またはlambda_expressionキャプチャされた外部変数の同じ (場合によっては空) のセットをインスタンスは許可されている (ただし必要ありません) と同じにします。Invocation list entries produced from evaluation of semantically identical anonymous_method_expressions or lambda_expressions with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.

等値演算子と nullEquality operators and null

==!=演算子を null 許容型およびその他がの値の 1 つのオペランドの許可、null操作の定義済みまたはユーザー定義の演算子 (でリフトされていない形式またはリフト形式) が存在しない場合でも、リテラル。The == and != operators permit one operand to be a value of a nullable type and the other to be the null literal, even if no predefined or user-defined operator (in unlifted or lifted form) exists for the operation.

フォームのいずれかの操作For an operation of one of the forms

x == null
null == x
x != null
null != x

場所x演算子のオーバー ロードの解決の場合、null 許容型の式は、(二項演算子のオーバー ロードの解決) から、適用可能な演算子の結果の検索に失敗が計算された代わりに、 HasValueプロパティのxします。where x is an expression of a nullable type, if operator overload resolution (Binary operator overload resolution) fails to find an applicable operator, the result is instead computed from the HasValue property of x. 具体的には、最初の 2 つのフォームに変換!x.HasValue、および最後の 2 つのフォームに変換がx.HasValueします。Specifically, the first two forms are translated into !x.HasValue, and last two forms are translated into x.HasValue.

演算子The is operator

is演算子を使用して動的にオブジェクトの実行時の型が指定された型と互換性をチェックします。The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. 操作の結果E is Tここで、E式を指定し、T型、ブール値を示す値かどうかE型に正常に変換できますTをボックス化の参照変換によって変換またはボックス化解除の変換。The result of the operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. 操作は、すべての型パラメーターの型引数が置き換えられた後に次のように評価されます。The operation is evaluated as follows, after type arguments have been substituted for all type parameters:

  • 場合E、匿名関数は、コンパイル時エラーが発生しました。If E is an anonymous function, a compile-time error occurs
  • 場合Eメソッド グループ、またはnullリテラルの場合は、の種類E参照型または null 許容型の値がEは、結果は false、null。If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.
  • それ以外の場合、Dの動的な型を表すE次のようにします。Otherwise, let D represent the dynamic type of E as follows:
    • 場合の種類E、参照型では、Dによってインスタンスの参照の実行時の型は、Eします。If the type of E is a reference type, D is the run-time type of the instance reference by E.
    • 場合の種類Eが null 許容型では、 D null 許容型の基になる型です。If the type of E is a nullable type, D is the underlying type of that nullable type.
    • 場合の種類Enull 非許容値型では、Dの型であるEします。If the type of E is a non-nullable value type, D is the type of E.
  • 操作の結果が異なりますDT次のようにします。The result of the operation depends on D and T as follows:
    • 場合T、参照型では、結果は true 場合DTは場合に、同じ型でDは、参照型からの暗黙的な参照変換DTが存在する場合、またはD値型からボックス化変換DT存在します。If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
    • 場合Tが null 許容型では、結果は true 場合Dの基になる型は、Tします。If T is a nullable type, the result is true if D is the underlying type of T.
    • 場合Tnull 非許容値型では、結果は true 場合DTは同じ型。If T is a non-nullable value type, the result is true if D and T are the same type.
    • それ以外の場合、結果は false です。Otherwise, the result is false.

ユーザー定義変換がによっていないと見なされることに注意してください、is演算子。Note that user defined conversions, are not considered by the is operator.

演算子として、The as operator

as演算子を使用して、特定の参照型または null 許容型に値を明示的に変換します。The as operator is used to explicitly convert a value to a given reference type or nullable type. キャスト式とは異なり (キャスト式)、as演算子が例外をスローしません。Unlike a cast expression (Cast expressions), the as operator never throws an exception. 代わりに、指定された変換ができない場合、結果の値はnullします。Instead, if the indicated conversion is not possible, the resulting value is null.

フォームの操作でE as TE式を指定する必要がありますとT参照型、参照型、または null 許容型を既知の型パラメーターである必要があります。In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. さらに、true の場合、次の少なくとも 1 つある必要があります。 またはそれ以外の場合、コンパイル時エラーが発生します。Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:

コンパイル時の型の場合Eないdynamic、操作E as Tと同じ結果になりますIf the compile-time type of E is not dynamic, the operation E as T produces the same result as

E is T ? (T)(E) : (T)null

ただし、E が評価されるのは 1 回だけです。except that E is only evaluated once. 最適化するために、コンパイラが期待できますE as T上記の拡張が含まれる 2 つの動的な型チェックではなく多くて 1 つ動的な型チェックを実行します。The compiler can be expected to optimize E as T to perform at most one dynamic type check as opposed to the two dynamic type checks implied by the expansion above.

コンパイル時の型の場合Edynamic、キャスト演算子とは異なり、as演算子が動的にバインドされていない (動的バインド)。If the compile-time type of E is dynamic, unlike the cast operator the as operator is not dynamically bound (Dynamic binding). そのため、拡張がここでは。Therefore the expansion in this case is:

E is T ? (T)(object)(E) : (T)null

ユーザー定義変換など、いくつかの変換が可能でないことに注意してください、as演算子と、キャスト式を使用する代わりに実行する必要があります。Note that some conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions.

In the example

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 
    }
}

型パラメーターTGは、クラスの制約があるため、参照型に呼ばれます。the type parameter T of G is known to be a reference type, because it has the class constraint. 型パラメーターUHないただし。 そのための使用、as演算子Hは許可されません。The type parameter U of H is not however; hence the use of the as operator in H is disallowed.

論理演算子Logical operators

&^、および|演算子は論理演算子と呼ばれます。The &, ^, and | operators are called the logical operators.

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、式を動的にバインドし、(動的バインド)。If an operand of a logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). この場合、式のコンパイル時の型はdynamic、コンパイル時の型を持つこれらのオペランドの実行時の型を使用して実行時に以下に示す解決が行わdynamicします。In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

フォームの操作のx op yここで、op論理演算子をオーバー ロードの解決のいずれか (二項演算子のオーバー ロードの解決) を適用して特定の演算子の実装を選択します。For an operation of the form x op y, where op is one of the logical operators, overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. オペランドは、選択した演算子のパラメーターの型に変換され、結果の型が演算子の戻り値の型。The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

定義済みの論理演算子は、次のセクションで説明します。The predefined logical operators are described in the following sections.

整数の論理演算子Integer logical operators

定義済みの整数の論理演算子は次のとおりです。The predefined integer logical operators are:

int operator &(int x, int y);
uint operator &(uint x, uint 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);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);

int operator ^(int x, int y);
uint operator ^(uint x, uint y);
long operator ^(long x, long y);
ulong operator ^(ulong x, ulong y);

&演算子はビットごとの計算論理ANDの 2 つのオペランド、|演算子はビット演算を計算論理ORの 2 つのオペランドと^演算子はビットごとの排他的論理を計算ORの 2 つのオペランド。The & operator computes the bitwise logical AND of the two operands, the | operator computes the bitwise logical OR of the two operands, and the ^ operator computes the bitwise logical exclusive OR of the two operands. オーバーフローは、これらの操作からではありません。No overflows are possible from these operations.

列挙論理演算子Enumeration logical operators

すべての列挙型E暗黙的に、次の定義済みの論理演算子を提供します。Every enumeration type E implicitly provides the following predefined logical operators:

E operator &(E x, E y);
E operator |(E x, E y);
E operator ^(E x, E y);

評価結果x op yここで、xy列挙型の式はE基になる型U、およびop論理演算子の 1 つと同じでは正確に評価する(E)((U)x op (U)y)します。The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the logical operators, is exactly the same as evaluating (E)((U)x op (U)y). つまり、列挙型の論理演算子は、2 つのオペランドの基になる型の論理操作を実行するだけです。In other words, the enumeration type logical operators simply perform the logical operation on the underlying type of the two operands.

ブール論理演算子Boolean logical operators

定義済みのブール型の論理演算子は次のとおりです。The predefined boolean logical operators are:

bool operator &(bool x, bool y);
bool operator |(bool x, bool y);
bool operator ^(bool x, bool y);

xy の両方が true であれば、x & y の結果は true です。The result of x & y is true if both x and y are true. それ以外の場合、結果は false です。Otherwise, the result is false.

結果x | ytrue場合xまたはytrueします。The result of x | y is true if either x or y is true. それ以外の場合、結果は false です。Otherwise, the result is false.

結果x ^ ytrue場合xtrueyfalse、またはxfalseytrueします。The result of x ^ y is true if x is true and y is false, or x is false and y is true. それ以外の場合、結果は false です。Otherwise, the result is false. 型のオペランドが場合bool^演算子と同じ結果を計算する、!=演算子。When the operands are of type bool, the ^ operator computes the same result as the != operator.

Null 許容のブール論理演算子Nullable boolean logical operators

Null 許容のブール型bool?3 つの値を表すことができますtruefalse、およびnull、概念的には、SQL のブール式に使用される 3 つの値の型に似ています。The nullable boolean type bool? can represent three values, true, false, and null, and is conceptually similar to the three-valued type used for boolean expressions in SQL. によって生成される結果を確実に、&|演算子のbool?オペランドは、SQL の 3 値論理と一貫性のあるが、次の定義済みの演算子が提供は。To ensure that the results produced by the & and | operators for bool? operands are consistent with SQL's three-valued logic, the following predefined operators are provided:

bool? operator &(bool? x, bool? y);
bool? operator |(bool? x, bool? y);

次の表に、これらの演算子、値のすべての組み合わせによって生成される結果truefalse、およびnullします。The following table lists the results produced by these operators for all combinations of the values true, false, and null.

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

条件付き論理演算子Conditional logical operators

&&||演算子は、条件付き論理演算子と呼ばれます。The && and || operators are called the conditional logical operators. 「ショート サーキット」論理演算子と呼ばれます。They are also called the "short-circuiting" logical operators.

conditional_and_expression
    : inclusive_or_expression
    | conditional_and_expression '&&' inclusive_or_expression
    ;

conditional_or_expression
    : conditional_and_expression
    | conditional_or_expression '||' conditional_and_expression
    ;

&&||演算子は、条件付きのバージョンの&|演算子。The && and || operators are conditional versions of the & and | operators:

  • 操作x && y、操作に対応するx & yことを除いて、y場合にのみ評価されますxないfalseします。The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is not false.
  • 操作x || y、操作に対応するx | yことを除いて、y場合にのみ評価されますxないtrueします。The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.

条件付き論理演算子のオペランドがコンパイル時の型を持つかどうかdynamic、式を動的にバインドし、(動的バインド)。If an operand of a conditional logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). この場合、式のコンパイル時の型はdynamic、コンパイル時の型を持つこれらのオペランドの実行時の型を使用して実行時に以下に示す解決が行わdynamicします。In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

フォームの操作をx && yまたはx || yオーバー ロードの解決を適用することによって処理されます (二項演算子のオーバー ロードの解決)、操作が書き込まれた場合、x & yまたはx | yします。An operation of the form x && y or x || y is processed by applying overload resolution (Binary operator overload resolution) as if the operation was written x & y or x | y. そうしたらThen,

条件付き論理演算子を直接オーバー ロードすることはできません。It is not possible to directly overload the conditional logical operators. ただし、通常の論理演算子の観点から、条件付き論理演算子が評価されるため、通常の論理演算子のオーバー ロードは、一定の制限もと見なされます、条件付き論理演算子のオーバー ロード。However, because the conditional logical operators are evaluated in terms of the regular logical operators, overloads of the regular logical operators are, with certain restrictions, also considered overloads of the conditional logical operators. 詳細についてはこのユーザー定義の条件付き論理演算子します。This is described further in User-defined conditional logical operators.

ブール型の条件付き論理演算子Boolean conditional logical operators

ときのオペランドは、&&または||bool、や、該当する定義しない型のオペランドがoperator &またはoperator |への暗黙的な変換を定義する操作を行いますが、bool操作が次のように処理されます。When the operands of && or || are of type bool, or when the operands are of types that do not define an applicable operator & or operator |, but do define implicit conversions to bool, the operation is processed as follows:

  • 操作x && yとして評価されますx ? y : falseします。The operation x && y is evaluated as x ? y : false. つまり、xが最初に評価され、型に変換するboolします。In other words, x is first evaluated and converted to type bool. その後、場合xtrueyが評価され、型に変換bool操作の結果になります。Then, if x is true, y is evaluated and converted to type bool, and this becomes the result of the operation. 操作の結果は、それ以外の場合、falseします。Otherwise, the result of the operation is false.
  • 操作x || yとして評価されますx ? true : yします。The operation x || y is evaluated as x ? true : y. つまり、xが最初に評価され、型に変換するboolします。In other words, x is first evaluated and converted to type bool. 場合はその後、xtrue、操作の結果はtrueします。Then, if x is true, the result of the operation is true. それ以外の場合、yが評価され、型に変換するbool操作の結果になります。Otherwise, y is evaluated and converted to type bool, and this becomes the result of the operation.

ユーザー定義の条件付き論理演算子User-defined conditional logical operators

ときに、オペランドの&&または||は、該当する宣言型のユーザー定義operator &またはoperator |、場所で true の場合、ある、次の両方必要がありますTは選択した演算子が宣言されている型です。When the operands of && or || are of types that declare an applicable user-defined operator & or operator |, both of the following must be true, where T is the type in which the selected operator is declared:

  • 戻り値の型と、選択した演算子の各パラメーターの型である必要がありますTします。The return type and the type of each parameter of the selected operator must be T. つまり、演算子を論理計算ANDまたは論理OR型の 2 つのオペランドのT、型の結果を返す必要がありますTします。In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T.
  • T 宣言を含める必要がありますoperator trueoperator falseします。T must contain declarations of operator true and operator false.

バインディング エラーは、これらの要件のいずれかが満たされない場合に発生します。A binding-time error occurs if either of these requirements is not satisfied. それ以外の場合、&&または||操作は、ユーザー定義を組み合わせることによって評価されますoperator trueまたはoperator false選択したユーザー定義演算子を使用します。Otherwise, the && or || operation is evaluated by combining the user-defined operator true or operator false with the selected user-defined operator:

  • 操作x && yとして評価されますT.false(x) ? x : T.&(x, y)ここで、T.false(x)の呼び出し、operator falseで宣言されているT、およびT.&(x, y)の選択した呼び出しoperator &します。The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. つまり、xが最初に評価およびoperator falseがどうかを判断の結果に対して呼び出すxが確実に false。In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. その後、ifxが間違いなく false の場合、操作の結果は、以前に計算値xします。Then, if x is definitely false, the result of the operation is the value previously computed for x. それ以外の場合、yが評価されと、選択したoperator &が以前に計算値で呼び出されるx計算された値とy操作の結果を生成します。Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
  • 操作x || yとして評価されますT.true(x) ? x : T.|(x, y)ここで、T.true(x)の呼び出し、operator trueで宣言されているT、およびT.|(x,y)の選択した呼び出しoperator|します。The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x,y) is an invocation of the selected operator|. つまり、xが最初に評価およびoperator trueがどうかを判断の結果に対して呼び出すxが確実に true です。In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. その後、ifxが間違いなく true の場合、操作の結果は、以前に計算値xします。Then, if x is definitely true, the result of the operation is the value previously computed for x. それ以外の場合、yが評価されと、選択したoperator |が以前に計算値で呼び出されるx計算された値とy操作の結果を生成します。Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.

これらの操作が指定された式のいずれかでxはによって指定された式で 1 回、評価だけyはないか、評価、1 回だけ評価します。In either of these operations, the expression given by x is only evaluated once, and the expression given by y is either not evaluated or evaluated exactly once.

実装する型の例についてはoperator trueoperator falseを参照してくださいブール型のデータベースします。For an example of a type that implements operator true and operator false, see Database boolean type.

Null 合体演算子The null coalescing operator

??演算子は、null 合体演算子と呼ばれます。The ?? operator is called the null coalescing operator.

null_coalescing_expression
    : conditional_or_expression
    | conditional_or_expression '??' null_coalescing_expression
    ;

フォームの場合は、null 結合式a ?? b必要anull 許容型または参照型であります。A null coalescing expression of the form a ?? b requires a to be of a nullable type or reference type. 場合anull 以外の場合は、結果a ?? ba、それ以外の結果はbします。If a is non-null, the result of a ?? b is a; otherwise, the result is b. 操作の評価b場合にのみaが null です。The operation evaluates b only if a is null.

Null 合体演算子の右から左は"右から左へ"です。The null coalescing operator is right-associative, meaning that operations are grouped from right to left. たとえば、フォームの式a ?? b ?? cとして評価されますa ?? (b ?? c)します。For example, an expression of the form a ?? b ?? c is evaluated as a ?? (b ?? c). 一般に用語、フォームの式E1 ?? E2 ?? ... ?? Enオペランドの最初の null 以外の場合、またはすべてのオペランドが null の場合は null を返します。In general terms, an expression of the form E1 ?? E2 ?? ... ?? En returns the first of the operands that is non-null, or null if all operands are null.

式の型a ?? b暗黙の変換がオペランドに対して使用可能なによって異なります。The type of the expression a ?? b depends on which implicit conversions are available on the operands. 種類の優先度の順序でa ?? bA0A、またはBここで、Aの種類は、 a (されるa型があります)、Bの種類ですb(されるb型があります)、およびA0の基になる型は、A場合Aが null 許容型では、またはAそれ以外の場合。In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. 具体的には、a ?? bように処理されます。Specifically, a ?? b is processed as follows:

  • 場合Aが存在し、ない null 許容型または参照型では、コンパイル時エラーが発生します。If A exists and is not a nullable type or a reference type, a compile-time error occurs.
  • 場合b動的な式は、結果型はdynamicします。If b is a dynamic expression, the result type is dynamic. 実行時に、aが最初に評価します。At run-time, a is first evaluated. 場合aが null でないaは、動的に変換し、これが結果になります。If a is not null, a is converted to dynamic, and this becomes the result. それ以外の場合、bが評価され、結果になります。Otherwise, b is evaluated, and this becomes the result.
  • の場合Aが存在する null 許容型であり、からの暗黙的な変換が存在するbA0、結果型はA0します。Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. 実行時に、aが最初に評価します。At run-time, a is first evaluated. 場合aが null でないa型にラップされてA0結果になります。If a is not null, a is unwrapped to type A0, and this becomes the result. それ以外の場合、bが評価され、型に変換するA0結果になります。Otherwise, b is evaluated and converted to type A0, and this becomes the result.
  • の場合Aが存在するからの暗黙的な変換が存在してbA、結果型はAします。Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. 実行時に、aが最初に評価します。At run-time, a is first evaluated. 場合aが null でないa結果になります。If a is not null, a becomes the result. それ以外の場合、bが評価され、型に変換するA結果になります。Otherwise, b is evaluated and converted to type A, and this becomes the result.
  • の場合b型を持つBからの暗黙的な変換が存在してaB、結果型はBします。Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. 実行時に、aが最初に評価します。At run-time, a is first evaluated. 場合aが null でないa型にラップされてA0(場合Aが存在し、null 許容) と型に変換されたB結果になります。If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. それ以外の場合、bが評価され、結果になります。Otherwise, b is evaluated and becomes the result.
  • それ以外の場合、abは、互換性のないと、コンパイル時エラーが発生します。Otherwise, a and b are incompatible, and a compile-time error occurs.

条件演算子Conditional operator

?:演算子は条件演算子と呼ばれます。The ?: operator is called the conditional operator. 三項演算子にも呼び出されます。It is at times also called the ternary operator.

conditional_expression
    : null_coalescing_expression
    | null_coalescing_expression '?' expression ':' expression
    ;

フォームの条件式b ? x : y条件を最初に評価するbします。A conditional expression of the form b ? x : y first evaluates the condition b. その後、ifbtruexが評価され、操作の結果になります。Then, if b is true, x is evaluated and becomes the result of the operation. それ以外の場合、yが評価され、操作の結果になります。Otherwise, y is evaluated and becomes the result of the operation. 条件式を決して両方評価xyします。A conditional expression never evaluates both x and y.

条件演算子の右から左は"右から左へ"です。The conditional operator is right-associative, meaning that operations are grouped from right to left. たとえば、フォームの式a ? b : c ? d : eとして評価されますa ? b : (c ? d : e)します。For example, an expression of the form a ? b : c ? d : e is evaluated as a ? b : (c ? d : e).

最初のオペランド、?:演算子に暗黙的に変換できる式である必要がありますbool、または実装する型の式operator trueします。The first operand of the ?: operator must be an expression that can be implicitly converted to bool, or an expression of a type that implements operator true. どちらもこれらの要件が満たされている場合、コンパイル時エラーが発生します。If neither of these requirements is satisfied, a compile-time error occurs.

2 番目と 3 番目のオペランドxy?:演算子は、条件式の種類を制御します。The second and third operands, x and y, of the ?: operator control the type of the conditional expression.

  • 場合x型を持つXy型を持つYIf x has type X and y has type Y then
    • 暗黙の変換 (暗黙的な変換) から存在するXYがからではなくYX、しY条件式の種類です。If an implicit conversion (Implicit conversions) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
    • 暗黙の変換 (暗黙的な変換) から存在するYXがからではなくXY、しX条件式の種類です。If an implicit conversion (Implicit conversions) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
    • それ以外の場合、式の型を決定できないと、コンパイル時エラーが発生します。Otherwise, no expression type can be determined, and a compile-time error occurs.
  • だけの場合のいずれかのxy種類、およびその両方を持つxyの条件付きの式の型は、その型に暗黙的に変換されます。If only one of x and y has a type, and both x and y, of are implicitly convertible to that type, then that is the type of the conditional expression.
  • それ以外の場合、式の型を決定できないと、コンパイル時エラーが発生します。Otherwise, no expression type can be determined, and a compile-time error occurs.

フォームの条件式の実行時の処理b ? x : y次の手順で構成されています。The run-time processing of a conditional expression of the form b ? x : y consists of the following steps:

  • 最初に、bが評価され、およびboolの値b決定されます。First, b is evaluated, and the bool value of b is determined:
    • 暗黙の変換の種類からbboolこの暗黙の変換が生成するために実行されますが、存在する、bool値。If an implicit conversion from the type of b to bool exists, then this implicit conversion is performed to produce a bool value.
    • それ以外の場合、operator trueの型によって定義されたbが生成するために呼び出される、bool値。Otherwise, the operator true defined by the type of b is invoked to produce a bool value.
  • 場合、bool前の手順で生成される値はtrue、しxが評価され、条件付きの式の型に変換し、条件付きの式の結果になります。If the bool value produced by the step above is true, then x is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.
  • それ以外の場合、yが評価され、条件付きの式の型に変換し、条件付きの式の結果になります。Otherwise, y is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.

匿名関数式Anonymous function expressions

匿名関数"line"のメソッド定義を表す式を指定します。An anonymous function is an expression that represents an "in-line" method definition. 匿名関数はありません値または型自体が互換性のあるデリゲートまたは式ツリー型に変換可能です。An anonymous function does not have a value or type in and of itself, but is convertible to a compatible delegate or expression tree type. 匿名関数の変換の評価は、変換のターゲットの種類によって異なります。デリゲート型では、変換は、匿名関数を定義する方法を参照するデリゲート値に評価します。The evaluation of an anonymous function conversion depends on the target type of the conversion: If it is a delegate type, the conversion evaluates to a delegate value referencing the method which the anonymous function defines. 式ツリー型である場合は、オブジェクトの構造体としてのメソッドの構造を表す式ツリーに変換が評価されます。If it is an expression tree type, the conversion evaluates to an expression tree which represents the structure of the method as an object structure.

歴史的な理由は 2 つ構文種類あります匿名関数は、namely lambda_expressions とanonymous_method_expression秒。For historical reasons there are two syntactic flavors of anonymous functions, namely lambda_expressions and anonymous_method_expressions. ほぼすべての目的で、 lambda_expressions は簡潔でより表現力豊かなanonymous_method_expressionで、これは下位互換性の言語で表示します。For almost all purposes, lambda_expressions are more concise and expressive than anonymous_method_expressions, which remain in the language for backwards compatibility.

lambda_expression
    : anonymous_function_signature '=>' anonymous_function_body
    ;

anonymous_method_expression
    : 'delegate' explicit_anonymous_function_signature? block
    ;

anonymous_function_signature
    : explicit_anonymous_function_signature
    | implicit_anonymous_function_signature
    ;

explicit_anonymous_function_signature
    : '(' explicit_anonymous_function_parameter_list? ')'
    ;

explicit_anonymous_function_parameter_list
    : explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)*
    ;

explicit_anonymous_function_parameter
    : anonymous_function_parameter_modifier? type identifier
    ;

anonymous_function_parameter_modifier
    : 'ref'
    | 'out'
    ;

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
    : identifier
    ;

anonymous_function_body
    : expression
    | block
    ;

=> 演算子と代入 (=) は優先順位が同じで、結合規則が右から左です。The => operator has the same precedence as assignment (=) and is right-associative.

ある匿名関数をasync修飾子は、非同期関数でありで説明されている規則に従って反復子します。An anonymous function with the async modifier is an async function and follows the rules described in Iterators.

形式で匿名関数のパラメーターをlambda_expression明示的または暗黙的に型指定できます。The parameters of an anonymous function in the form of a lambda_expression can be explicitly or implicitly typed. 明示的に型指定されたパラメーター リストの各パラメーターの型を明示的に宣言します。In an explicitly typed parameter list, the type of each parameter is explicitly stated. 匿名関数が発生したコンテキストから、暗黙的に型指定されたパラメーターの一覧で、パラメーターの型の推論-互換性のあるデリゲート型または型を提供する式ツリーの型、匿名関数が変換される場合に具体的には、パラメーターの型 (匿名関数の変換)。In an implicitly typed parameter list, the types of the parameters are inferred from the context in which the anonymous function occurs—specifically, when the anonymous function is converted to a compatible delegate type or expression tree type, that type provides the parameter types (Anonymous function conversions).

1 つ、暗黙的に型指定されたパラメーターを使用して、匿名関数にパラメーター リストから、かっこは省略できます。In an anonymous function with a single, implicitly typed parameter, the parentheses may be omitted from the parameter list. つまり、フォームの匿名関数In other words, an anonymous function of the form

( param ) => expr

省略することができます。can be abbreviated to

param => expr

形式で匿名関数のパラメーター リスト、 anonymous_method_expressionは省略可能です。The parameter list of an anonymous function in the form of an anonymous_method_expression is optional. 指定した場合、パラメーターを明示的に入力する必要があります。If given, the parameters must be explicitly typed. 匿名の関数は任意のパラメーターを持つデリゲートに変換できる、そうでない場合の一覧が含まれていないoutパラメーター。If not, the anonymous function is convertible to a delegate with any parameter list not containing out parameters.

Aブロック匿名関数の本体に到達 (エンドポイントと到達可能性) しない限り、匿名関数で到達できないステートメント内に発生します。A block body of an anonymous function is reachable (End points and reachability) unless the anonymous function occurs inside an unreachable statement.

匿名関数の例をいくつかは、以下に従います。Some examples of anonymous functions follow below:

x => x + 1                              // Implicitly typed, expression body
x => { return x + 1; }                  // Implicitly typed, statement body
(int x) => x + 1                        // Explicitly typed, expression body
(int x) => { return x + 1; }            // Explicitly typed, statement 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
delegate { return 1 + 1; }              // Parameter list omitted

動作lambda_expressions とanonymous_method_expressions は、次の点を除けば同じです。The behavior of lambda_expressions and anonymous_method_expressions is the same except for the following points:

  • anonymous_method_expressions 許可を完全に省略パラメーター リストでもデリゲート パラメーターの値の一覧の型を生成します。anonymous_method_expressions permit the parameter list to be omitted entirely, yielding convertibility to delegate types of any list of value parameters.
  • lambda_expressions パラメーターの型は省略され、一方の推論を許可するanonymous_method_expressions がパラメーターの型を明示的に指定する必要があります。lambda_expressions permit parameter types to be omitted and inferred whereas anonymous_method_expressions require parameter types to be explicitly stated.
  • 本文をlambda_expressionは式またはステートメント ブロックを指定できますの本文をanonymous_method_expressionステートメント ブロックにする必要があります。The body of a lambda_expression can be an expression or a statement block whereas the body of an anonymous_method_expression must be a statement block.
  • のみlambda_expressions がある互換性のある式ツリー型への変換 (式ツリー型)。Only lambda_expressions have conversions to compatible expression tree types (Expression tree types).

匿名関数のシグネチャAnonymous function signatures

省略可能なanonymous_function_signature匿名関数の名前と必要に応じて、匿名関数の仮パラメーターの種類を定義します。The optional anonymous_function_signature of an anonymous function defines the names and optionally the types of the formal parameters for the anonymous function. 匿名関数のパラメーターのスコープは、 anonymous_function_bodyします。The scope of the parameters of the anonymous function is the anonymous_function_body. (スコープ) 匿名メソッド本体の宣言領域の構成 (指定された) 場合は、パラメーター リストと共に (宣言)。(Scopes) Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space (Declarations). ローカル変数、ローカル定数またはそのスコープに含まれるパラメーターの名前と一致する匿名関数のパラメーターの名前のコンパイル時エラーであるため、 anonymous_method_expressionまたはlambda_式します。It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the anonymous_method_expression or lambda_expression.

匿名関数がある場合、 explicit_anonymous_function_signature、互換性のあるデリゲート型と式ツリー型のセットは同じ順序で、同じパラメーターの型および修飾子を持つものに制限されています。If an anonymous function has an explicit_anonymous_function_signature, then the set of compatible delegate types and expression tree types is restricted to those that have the same parameter types and modifiers in the same order. メソッド グループ変換とは対照的 (メソッド グループ変換)、匿名関数のパラメーター型の反変性がサポートされていません。In contrast to method group conversions (Method group conversions), contra-variance of anonymous function parameter types is not supported. 匿名関数がない場合、 anonymous_function_signature、互換性のあるデリゲート型と式ツリー型のセットがないものだけに制限し、outパラメーター。If an anonymous function does not have an anonymous_function_signature, then the set of compatible delegate types and expression tree types is restricted to those that have no out parameters.

なお、 anonymous_function_signature属性またはパラメーター配列に含めることはできません。Note that an anonymous_function_signature cannot include attributes or a parameter array. ただし、 anonymous_function_signatureパラメーター リスト持つにはには、パラメーター配列が含まれています。 デリゲート型と互換性があります。Nevertheless, an anonymous_function_signature may be compatible with a delegate type whose parameter list contains a parameter array.

互換性のあるがコンパイル時に引き続き失敗する場合でも、式ツリー型に変換をまた (式ツリー型)。Note also that conversion to an expression tree type, even if compatible, may still fail at compile-time (Expression tree types).

匿名関数の本体Anonymous function bodies

本文 (またはブロック) 匿名関数は、次の規則に従います。The body (expression or block) of an anonymous function is subject to the following rules:

  • 匿名関数には、署名が含まれている場合、シグネチャで指定されたパラメーターは本体で使用できます。If the anonymous function includes a signature, the parameters specified in the signature are available in the body. デリゲート型またはパラメーターを持つ式の型に変換できる場合は、匿名関数のシグネチャはありません (匿名関数の変換) が、パラメーターは、本文にアクセスできません。If the anonymous function has no signature it can be converted to a delegate type or expression type having parameters (Anonymous function conversions), but the parameters cannot be accessed in the body.
  • 除くrefまたはout最も外側の署名 (存在する場合) で指定されたパラメーター、コンパイル時エラー、本文にアクセスするには匿名関数をrefまたはoutパラメーター。Except for ref or out parameters specified in the signature (if any) of the nearest enclosing anonymous function, it is a compile-time error for the body to access a ref or out parameter.
  • ときの種類this、構造体型には、コンパイル時エラー、本文にアクセスするにはthisします。When the type of this is a struct type, it is a compile-time error for the body to access this. これは true かどうか、アクセスが明示的な (としてでthis.x) または暗黙的な (とx場所x構造体のインスタンス メンバー)。This is true whether the access is explicit (as in this.x) or implicit (as in x where x is an instance member of the struct). 単に、このルールは、このようなアクセスを禁止し、メンバーの検索結果、構造体のメンバーであるかどうかには影響しません。This rule simply prohibits such access and does not affect whether member lookup results in a member of the struct.
  • 本体が外側の変数へのアクセス (外部変数) 匿名関数の。The body has access to the outer variables (Outer variables) of the anonymous function. 外部変数へのアクセスは、一度にアクティブになっている変数のインスタンスを参照、 lambda_expressionまたはanonymous_method_expressionが評価されます (の評価匿名関数式)。Access of an outer variable will reference the instance of the variable that is active at the time the lambda_expression or anonymous_method_expression is evaluated (Evaluation of anonymous function expressions).
  • コンパイル時エラーを含む本文には、gotoステートメントでは、breakステートメント、またはcontinue対象である、本文の外側、または含まれている匿名関数の本体内のステートメント。It is a compile-time error for the body to contain a goto statement, break statement, or continue statement whose target is outside the body or within the body of a contained anonymous function.
  • Areturn本体のステートメントでは、最も近い外側の呼び出しから制御を返します、外側の関数メンバーからではなく、匿名関数です。A return statement in the body returns control from an invocation of the nearest enclosing anonymous function, not from the enclosing function member. 指定された式をreturnステートメントは、デリゲート型または式ツリー型の戻り値の型に暗黙的に変換可能である必要があります囲む最も近いlambda_expressionまたはanonymous_method_expression変換されます (匿名関数の変換)。An expression specified in a return statement must be implicitly convertible to the return type of the delegate type or expression tree type to which the nearest enclosing lambda_expression or anonymous_method_expression is converted (Anonymous function conversions).

評価版の呼び出しから以外の匿名関数のブロックを実行する方法があるかどうかは明示的に指定されていません、 lambda_expressionまたはanonymous_method_expression.It is explicitly unspecified whether there is any way to execute the block of an anonymous function other than through evaluation and invocation of the lambda_expression or anonymous_method_expression. 具体的には、コンパイラが 1 つを合成することで、匿名関数を実装することをまたは以上の名前付きメソッドまたは型。In particular, the compiler may choose to implement an anonymous function by synthesizing one or more named methods or types. このような合成要素の名前は、コンパイラを使用するために予約された形式でなければなりません。The names of any such synthesized elements must be of a form reserved for compiler use.

オーバー ロードの解決と匿名関数Overload resolution and anonymous functions

匿名関数の引数リストでは、型の推定に参加し、オーバー ロードの解決。Anonymous functions in an argument list participate in type inference and overload resolution. 参照してください型推論オーバー ロードの解決の厳密な規則です。Please refer to Type inference and Overload resolution for the exact rules.

次の例は、匿名関数のオーバー ロードの解決への影響を示しています。The following example illustrates the effect of anonymous functions on overload resolution.

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メソッド。The ItemList<T> class has two Sum methods. それぞれ、selector引数で、リスト項目から経由での合計に値を抽出します。Each takes a selector argument, which extracts the value to sum over from a list item. 抽出された値には、いずれかを指定できます、intまたはdoubleし、結果の合計は、いずれかでも同様に、intまたはdoubleします。The extracted value can be either an int or a double and the resulting sum is likewise either an int or a double.

Sumリストの順序の詳細行の合計を計算するメソッドを使用例でした。The Sum methods could for example be used to compute sums from a list of detail lines in an order.

class Detail
{
    public int UnitCount;
    public double UnitPrice;
    ...
}

void ComputeSums() {
    ItemList<Detail> orderDetails = GetOrderDetails(...);
    int totalUnits = orderDetails.Sum(d => d.UnitCount);
    double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount);
    ...
}

最初の呼び出しでorderDetails.Sumの両方をSumメソッドは、適用可能なため、匿名関数d => d. UnitCountは両方と互換性がFunc<Detail,int>Func<Detail,double>します。In the first invocation of orderDetails.Sum, both Sum methods are applicable because the anonymous function d => d. UnitCount is compatible with both Func<Detail,int> and Func<Detail,double>. ただし、オーバー ロードの解決が最初に検出Sumメソッドのためへの変換Func<Detail,int>への変換よりも優れてFunc<Detail,double>します。However, overload resolution picks the first Sum method because the conversion to Func<Detail,int> is better than the conversion to Func<Detail,double>.

2 つ目の呼び出しでorderDetails.Sumし、2 番目Sumメソッドは、適用可能なため、匿名関数d => d.UnitPrice * d.UnitCount型の値を生成doubleします。In the second invocation of orderDetails.Sum, only the second Sum method is applicable because the anonymous function d => d.UnitPrice * d.UnitCount produces a value of type double. したがって、オーバー ロードの解決は、2 つ目を取得Sumその呼び出しのメソッド。Thus, overload resolution picks the second Sum method for that invocation.

匿名関数と動的バインディングAnonymous functions and dynamic binding

匿名関数は、受信者、引数または動的に連結演算のオペランドにすることはできません。An anonymous function cannot be a receiver, argument or operand of a dynamically bound operation.

外部変数Outer variables

任意のローカル変数、パラメーターの値、またはがスコープに含まれるパラメーター配列、 lambda_expressionまたはanonymous_method_expressionと呼ばれますが、外部変数匿名関数です。Any local variable, value parameter, or parameter array whose scope includes the lambda_expression or anonymous_method_expression is called an outer variable of the anonymous function. クラスのインスタンス関数のメンバーで、this値が値を持つパラメーターと見なされ、関数メンバー内に含まれるすべての匿名関数の外部変数は、します。In an instance function member of a class, the this value is considered a value parameter and is an outer variable of any anonymous function contained within the function member.

外部変数のキャプチャCaptured outer variables

外部変数は、匿名関数によって参照される、外部変数があると言います。キャプチャによって匿名関数です。When an outer variable is referenced by an anonymous function, the outer variable is said to have been captured by the anonymous function. 通常、ローカル変数の有効期間は、ブロックまたはそれが関連付けられているステートメントの実行に制限されています (ローカル変数)。Ordinarily, the lifetime of a local variable is limited to execution of the block or statement with which it is associated (Local variables). ただし、キャプチャされた外部変数の有効期間は、デリゲートまで少なくとも拡張または匿名関数から作成された式ツリーがガベージ コレクションの対象になります。However, the lifetime of a captured outer variable is extended at least until the delegate or expression tree created from the anonymous function becomes eligible for garbage collection.

In the example

using System;

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(の末尾まで発生しませんが、ガベージ コレクションの対象になります。プログラム)。the local variable x is captured by the anonymous function, and the lifetime of x is extended at least until the delegate returned from F becomes eligible for garbage collection (which doesn't happen until the very end of the program). 匿名関数の呼び出しごとの動作の同じインスタンスであるためx例の出力には。Since each invocation of the anonymous function operates on the same instance of x, the output of the example is:

1
2
3

匿名関数によって、ローカル変数または値を持つパラメーターがキャプチャされると、ローカル変数またはパラメーターは不要になったと見なされます固定変数 (固定属性と移動可能変数) は代わりに、移動可能と見なされますが、変数。When a local variable or a value parameter is captured by an anonymous function, the local variable or parameter is no longer considered to be a fixed variable (Fixed and moveable variables), but is instead considered to be a moveable variable. したがって、unsafeキャプチャされた外部変数のアドレスを取得するコードを使用する必要があります最初、fixedステートメント、変数を解決します。Thus any unsafe code that takes the address of a captured outer variable must first use the fixed statement to fix the variable.

なお uncaptured の変数とは異なり、キャプチャされたローカル変数を複数の実行スレッドを同時に公開できます。Note that unlike an uncaptured variable, a captured local variable can be simultaneously exposed to multiple threads of execution.

ローカル変数のインスタンス化Instantiation of local variables

ローカル変数があると見なされますインスタンス化実行が、変数のスコープに入ったとき。A local variable is considered to be instantiated when execution enters the scope of the variable. 次のメソッドの呼び出し時に、ローカル変数など、xがインスタンス化され、3 回の初期化など、ループの反復ごとに 1 回。For example, when the following method is invoked, the local variable x is instantiated and initialized three times—once for each iteration of the loop.

static void F() {
    for (int i = 0; i < 3; i++) {
        int x = i * 2 + 1;
        ...
    }
}

ただしの宣言の移動xに 1 つのインスタンス化のループの外側x:However, moving the declaration of x outside the loop results in a single instantiation of x:

static void F() {
    int x;
    for (int i = 0; i < 3; i++) {
        x = i * 2 + 1;
        ...
    }
}

キャプチャされていないときに、ローカル変数がインスタンス化される正確にどのくらいの頻度を確認する方法はありません: インスタンス化の有効期間が互いに離れて、ため、単に同じストレージの場所を使用するには、各インスタンスのことができます。When not captured, there is no way to observe exactly how often a local variable is instantiated—because the lifetimes of the instantiations are disjoint, it is possible for each instantiation to simply use the same storage location. ただし、ローカル変数をキャプチャする匿名関数をインスタンス化の効果は明らかになります。However, when an anonymous function captures a local variable, the effects of instantiation become apparent.

例では、The example

using System;

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();
    }
}

この例では、次のように出力されます。produces the output:

1
3
5

ただしの宣言xループの外側に移動されます。However, when the declaration of x is moved outside the loop:

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;
}

出力は次のとおりです。the output is:

5
5
5

For ループでは、繰り返し変数を宣言すると、その変数自体をループの外で宣言すると見なされます。If a for-loop declares an iteration variable, that variable itself is considered to be declared outside of the loop. したがって、自体の反復変数をキャプチャする例を変更した場合。Thus, if the example is changed to capture the iteration variable itself:

static D[] F() {
    D[] result = new D[3];
    for (int i = 0; i < 3; i++) {
        result[i] = () => { Console.WriteLine(i); };
    }
    return result;
}

反復変数の 1 つだけのインスタンスをキャプチャしたら、出力が生成されます。only one instance of the iteration variable is captured, which produces the output:

3
3
3

匿名関数のデリゲートは、いくつかのキャプチャされた変数を共有しながら他のユーザーの別のインスタンスがあることができます。It is possible for anonymous function delegates to share some captured variables yet have separate instances of others. たとえば場合、Fに変更されますFor example, if F is changed to

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("{0} {1}", ++x, ++y); };
    }
    return result;
}

3 つのデリゲートの同じインスタンスをキャプチャするxがのインスタンスを区切るy出力は。the three delegates capture the same instance of x but separate instances of y, and the output is:

1 1
2 1
3 1

個別の匿名関数には、外部変数の同じインスタンスをキャプチャできます。Separate anonymous functions can capture the same instance of an outer variable. 次に例を示します。In the example:

using System;

delegate void Setter(int value);

delegate int Getter();

class Test
{
    static void Main() {
        int x = 0;
        Setter s = (int value) => { x = value; };
        Getter g = () => { return x; };
        s(5);
        Console.WriteLine(g());
        s(10);
        Console.WriteLine(g());
    }
}

2 つの匿名関数は、ローカル変数の同じインスタンスをキャプチャx、したがって「通信できる」変数を通じてとします。the two anonymous functions capture the same instance of the local variable x, and they can thus "communicate" through that variable. この例の出力は次のとおりです。The output of the example is:

5
10

匿名関数式の評価Evaluation of anonymous function expressions

匿名関数F常にデリゲート型に変換する必要がありますDまたは式ツリー型E、直接、またはデリゲート作成式の実行によりnew D(F)します。An anonymous function F must always be converted to a delegate type D or an expression tree type E, either directly or through the execution of a delegate creation expression new D(F). 」の説明に従って、この変換は、匿名関数の結果を決定します。匿名関数の変換します。This conversion determines the result of the anonymous function, as described in Anonymous function conversions.

クエリ式Query expressions

クエリ式SQL や XQuery などのリレーショナルで階層的なクエリ言語に類似したクエリに対して統合言語の構文を提供します。Query expressions provide a language integrated syntax for queries that is similar to relational and hierarchical query languages such as SQL and XQuery.

query_expression
    : from_clause query_body
    ;

from_clause
    : 'from' type? identifier 'in' expression
    ;

query_body
    : query_body_clauses? select_or_group_clause query_continuation?
    ;

query_body_clauses
    : query_body_clause
    | query_body_clauses query_body_clause
    ;

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句。A query expression begins with a from clause and ends with either a select or group clause. 初期from句の後に 0 個以上をできますfromletwherejoinまたはorderby句。The initial from clause can be followed by zero or more from, let, where, join or orderby clauses. from句は、ジェネレーターの概要、範囲変数の要素範囲をシーケンスします。Each from clause is a generator introducing a range variable which ranges over the elements of a sequence. let句には前の範囲変数を使用して計算値を表す範囲変数が導入されています。Each let clause introduces a range variable representing a value computed by means of previous range variables. where句は結果から項目を除外するフィルター。Each where clause is a filter that excludes items from the result. join句がソース シーケンスの指定のキーと一致するペアを生成するもう 1 つのシーケンスのキーを比較します。Each join clause compares specified keys of the source sequence with keys of another sequence, yielding matching pairs. orderby句が指定した条件に従って項目を並べ替えます。最終的なselectまたはgroup句は、範囲変数の観点から結果の形状を指定します。Each orderby clause reorders items according to specified criteria.The final select or group clause specifies the shape of the result in terms of the range variables. 最後に、into句は、1 つのクエリの結果を後続のクエリでのジェネレーターとして扱うことでクエリを「接続」を使用できます。Finally, an into clause can be used to "splice" queries by treating the results of one query as a generator in a subsequent query.

クエリ式のあいまいさAmbiguities in query expressions

クエリ式には、「コンテキスト キーワード」、つまりを特定のコンテキストで特別な意味を持つ識別子の数が含まれています。Query expressions contain a number of "contextual keywords", i.e., identifiers that have special meaning in a given context. 具体的には、これらはfromwherejoinonequalsintoletorderbyascendingdescendingselectgroupby.Specifically these are from, where, join, on, equals, into, let, orderby, ascending, descending, select, group and by. キーワードまたは簡易名としてこれらの識別子の混在の使用によって発生するクエリ式のあいまいさを回避するためにこれらの識別子はキーワード時に考慮クエリ式内で任意の場所に発生します。In order to avoid ambiguities in query expressions caused by mixed use of these identifiers as keywords or simple names, these identifiers are considered keywords when occurring anywhere within a query expression.

この目的では、クエリ式は任意の式で始まる"from identifier「を除く任意のトークンが続く」;「,」=「または」,"。For this purpose, a query expression is any expression that starts with "from identifier" followed by any token except ";", "=" or ",".

クエリ式内で識別子としてこれらの単語を使用するには、先頭"@"(識別子)。In order to use these words as identifiers within a query expression, they can be prefixed with "@" (Identifiers).

クエリ式の変換Query expression translation

C# 言語では、クエリ式の実行のセマンティクスが指定されていません。The C# language does not specify the execution semantics of query expressions. 代わりに、クエリ式に準拠しているメソッドの呼び出しに変換、クエリ式パターン(、クエリ式パターン)。Rather, query expressions are translated into invocations of methods that adhere to the query expression pattern (The query expression pattern). 具体的には、クエリ式は、名前付きメソッドの呼び出しに変換WhereSelectSelectManyJoinGroupJoinOrderByOrderByDescendingThenByThenByDescendingGroupBy、およびCastします。」の説明に従って、これらのメソッドが特定のシグネチャと結果型が予想される、クエリ式パターンします。Specifically, query expressions are translated into invocations of methods named Where, Select, SelectMany, Join, GroupJoin, OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, and Cast.These methods are expected to have particular signatures and result types, as described in The query expression pattern. これらのメソッドは、クエリ対象のオブジェクトのインスタンス メソッドまたは外部のオブジェクトにある拡張メソッドを指定でき、クエリの実際の実行を実装します。These methods can be instance methods of the object being queried or extension methods that are external to the object, and they implement the actual execution of the query.

クエリ式からのメソッド呼び出しへの変換は、型のバインディングの前に発生した構文マップまたはオーバー ロードの解決が実行されています。The translation from query expressions to method invocations is a syntactic mapping that occurs before any type binding or overload resolution has been performed. 構文的に正しい変換のことが保証されますが、意味的に正しい c# コードを生成するためには保証されません。The translation is guaranteed to be syntactically correct, but it is not guaranteed to produce semantically correct C# code. 次のクエリ式の変換は、通常のメソッドの呼び出しとして処理されます結果として得られるメソッドの呼び出しをこの可能性がありますさらに発見し、エラーの例では、メソッドが存在しない場合、引数が正しくない型を持つ場合、またはメソッドがジェネリックの場合、。型の推論は失敗します。Following translation of query expressions, the resulting method invocations are processed as regular method invocations, and this may in turn uncover errors, for example if the methods do not exist, if arguments have wrong types, or if the methods are generic and type inference fails.

クエリ式は、考えられるさらなる削減がなくなるまで繰り返し次の変換を適用することで処理されます。A query expression is processed by repeatedly applying the following translations until no further reductions are possible. 翻訳は、アプリケーションの順序で並んでいる: 各セクションでは、前のセクションで翻訳が徹底的に、実行されることと、不足すると後、セクションがいない後で再訪問する同じクエリ式の処理に前提としています。The translations are listed in order of application: each section assumes that the translations in the preceding sections have been performed exhaustively, and once exhausted, a section will not later be revisited in the processing of the same query expression.

クエリ式では、範囲変数に代入することはできません。Assignment to range variables is not allowed in query expressions. ただし、c# の実装は、常にではありませんので、これも不可能になるここに示す構文変換の方法で、この制限を適用する許可されます。However a C# implementation is permitted to not always enforce this restriction, since this may sometimes not be possible with the syntactic translation scheme presented here.

特定の翻訳によって示される透過的な識別子を持つ範囲変数に挿入*します。Certain translations inject range variables with transparent identifiers denoted by *. 透過的な識別子の特殊なプロパティの説明でさらに透過的識別子します。The special properties of transparent identifiers are discussed further in Transparent identifiers.

継続を選択し、groupby 句Select and groupby clauses with continuations

連続したクエリ式A query expression with a continuation

from ... into x ...

変換されます。is translated into

from x in ( from ... ) ...

次のセクションでの翻訳がクエリされていないことを想定していますinto継続します。The translations in the following sections assume that queries have no into continuations.

例では、The example

from c in customers
group c by c.Country into g
select new { Country = g.Key, CustCount = g.Count() }

変換されます。is translated into

from g in
    from c in customers
    group c by c.Country
select new { Country = g.Key, CustCount = g.Count() }

最終的な変換は、します。the final translation of which is

customers.
GroupBy(c => c.Country).
Select(g => new { Country = g.Key, CustCount = g.Count() })

明示的な範囲変数の型Explicit range variable types

Afrom範囲変数の型を明示的に指定する句A from clause that explicitly specifies a range variable type

from T x in e

変換されます。is translated into

from x in ( e ) . Cast < T > ( )

Ajoin範囲変数の型を明示的に指定する句A join clause that explicitly specifies a range variable type

join T x in e on k1 equals k2

変換されます。is translated into

join x in ( e ) . Cast < T > ( ) on k1 equals k2

次のセクションでの翻訳では、クエリに明示的な範囲変数の型があるないことを前提としています。The translations in the following sections assume that queries have no explicit range variable types.

例では、The example

from Customer c in customers
where c.City == "London"
select c

変換されます。is translated into

from c in customers.Cast<Customer>()
where c.City == "London"
select c

最終的な変換は、します。the final translation of which is

customers.
Cast<Customer>().
Where(c => c.City == "London")

明示的な範囲変数の型は、非ジェネリックを実装するコレクションを照会するための便利なIEnumerableインターフェイスがジェネリックではないIEnumerable<T>インターフェイス。Explicit range variable types are useful for querying collections that implement the non-generic IEnumerable interface, but not the generic IEnumerable<T> interface. 上記の例では、となり場合customers型のArrayListします。In the example above, this would be the case if customers were of type ArrayList.

逆クエリ式Degenerate query expressions

形式のクエリ式A query expression of the form

from x in e select x

変換されます。is translated into

( e ) . Select ( x => x )

例では、The example

from c in customers
select c

変換されます。is translated into

customers.Select(c => c)

逆クエリ式では、普通に元の要素を選択する 1 つです。A degenerate query expression is one that trivially selects the elements of the source. 翻訳の後のフェーズでは、逆のクエリには、ソースで置き換えることで、その他の翻訳の手順で導入されたを削除します。A later phase of the translation removes degenerate queries introduced by other translation steps by replacing them with their source. こと、クエリの結果を確認するは決して自体には、ソース オブジェクトに式の種類とソースの id を明らかに、クエリのクライアント。It is important however to ensure that the result of a query expression is never the source object itself, as that would reveal the type and identity of the source to the client of the query. そのため、この手順が明示的に呼び出すことによって、ソース コードに直接書き込まれた逆のクエリを保護Selectソース。Therefore this step protects degenerate queries written directly in source code by explicitly calling Select on the source. 実装側の役目ですSelectとこれらのメソッドが、ソース オブジェクト自体を返さないことを確認するには、その他のクエリ演算子。It is then up to the implementers of Select and other query operators to ensure that these methods never return the source object itself.

Let、where、結合と orderby 句From, let, where, join and orderby clauses

2 番目のクエリ式from句が続く、selectA query expression with a second from clause followed by a select clause

from x1 in e1
from x2 in e2
select v

変換されます。is translated into

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )

2 番目のクエリ式from句が以外のものに後に、select句。A query expression with a second from clause followed by something other than a select clause:

from x1 in e1
from x2 in e2
...

変換されます。is translated into

from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )
...

クエリ式、letA query expression with a let clause

from x in e
let y = f
...

変換されます。is translated into

from * in ( e ) . Select ( x => new { x , y = f } )
...

クエリ式、whereA query expression with a where clause

from x in e
where f
...

変換されます。is translated into

from x in ( e ) . Where ( x => f )
...

クエリ式、join句なしで、into続けて、selectA query expression with a join clause without an into followed by a select clause

from x1 in e1
join x2 in e2 on k1 equals k2
select v

変換されます。is translated into

( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )

クエリ式、join句なしで、into以外のものによってその後に、selectA query expression with a join clause without an into followed by something other than a select clause

from x1 in e1
join x2 in e2 on k1 equals k2
...

変換されます。is translated into

from * in ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
...

クエリ式、join句、into続けて、selectA query expression with a join clause with an into followed by a select clause

from x1 in e1
join x2 in e2 on k1 equals k2 into g
select v

変換されます。is translated into

( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )

クエリ式、join句、into以外のものによってその後に、selectA query expression with a join clause with an into followed by something other than a select clause

from x1 in e1
join x2 in e2 on k1 equals k2 into g
...

変換されます。is translated into

from * in ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
...

クエリ式、orderbyA query expression with an orderby clause

from x in e
orderby k1 , k2 , ..., kn
...

変換されます。is translated into

from x in ( e ) . 
OrderBy ( x => k1 ) . 
ThenBy ( x => k2 ) .
... .
ThenBy ( x => kn )
...

句を指定している場合は、順序付け、descending方向インジケーターの呼び出しが、OrderByDescendingまたはThenByDescending代わりに生成されます。If an ordering clause specifies a descending direction indicator, an invocation of OrderByDescending or ThenByDescending is produced instead.

次の変換があることを想定していますありませんletwherejoinまたはorderby句、および 1 つ初期from各クエリ式の句。The following translations assume that there are no let, where, join or orderby clauses, and no more than the one initial from clause in each query expression.

例では、The example

from c in customers
from o in c.Orders
select new { c.Name, o.OrderID, o.Total }

変換されます。is translated into

customers.
SelectMany(c => c.Orders,
     (c,o) => new { c.Name, o.OrderID, o.Total }
)

例では、The example

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

変換されます。is translated into

from * in customers.
    SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

最終的な変換は、します。the final translation of which is

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アクセスは、それ以外の場合、コンパイラによって生成された識別子です。where x is a compiler generated identifier that is otherwise invisible and inaccessible.

例では、The example

from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new { o.OrderID, Total = t }

変換されます。is translated into

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 }

最終的な変換は、します。the final translation of which is

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 x is a compiler generated identifier that is otherwise invisible and inaccessible.

例では、The example

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new { c.Name, o.OrderDate, o.Total }

変換されます。is translated into

customers.Join(orders, c => c.CustomerID, o => o.CustomerID,
    (c, o) => new { c.Name, o.OrderDate, o.Total })

例では、The example

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 }

変換されます。is translated into

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 }

最終的な変換は、します。the final translation of which is

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)

場所xyは非表示とアクセスできない、それ以外の場合はコンパイラによって生成された識別子です。where x and y are compiler generated identifiers that are otherwise invisible and inaccessible.

例では、The example

from o in orders
orderby o.Customer.Name, o.Total descending
select o

最終的な変換にはhas the final translation

orders.
OrderBy(o => o.Customer.Name).
ThenByDescending(o => o.Total)

Select 句Select clauses

形式のクエリ式A query expression of the form

from x in e select v

変換されます。is translated into

( e ) . Select ( x => v )

v が識別子の場合を除き、x、翻訳は単にexcept when v is the identifier x, the translation is simply

( e )

次に例を示します。For example

from c in customers.Where(c => c.City == "London")
select c

単に変換されます。is simply translated into

customers.Where(c => c.City == "London")

Groupby 句Groupby clauses

形式のクエリ式A query expression of the form

from x in e group v by k

変換されます。is translated into

( e ) . GroupBy ( x => k , x => v )

v が識別子の場合を除き、x、翻訳は、except when v is the identifier x, the translation is

( e ) . GroupBy ( x => k )

例では、The example

from c in customers
group c.Name by c.Country

変換されます。is translated into

customers.
GroupBy(c => c.Country, c => c.Name)

透過的な識別子Transparent identifiers

特定の翻訳を持つ範囲変数を挿入する透過的識別子によって示される*します。Certain translations inject range variables with transparent identifiers denoted by *. 透過的な識別子は、適切な言語機能です。クエリ式の変換処理では中間の手順としてのみ存在するとします。Transparent identifiers are not a proper language feature; they exist only as an intermediate step in the query expression translation process.

クエリ変換では、透過的な識別子を挿入、ときに、変換の手順は匿名関数と匿名オブジェクト初期化子に透過識別子を伝達さらに。When a query translation injects a transparent identifier, further translation steps propagate the transparent identifier into anonymous functions and anonymous object initializers. これらのコンテキストでは、透過的な識別子は、次の動作をあります。In those contexts, transparent identifiers have the following behavior:

  • 透過識別子が、匿名関数にパラメーターとして発生したときに、関連付けられている匿名型のメンバーは自動的に匿名関数の本体のスコープ。When a transparent identifier occurs as a parameter in an anonymous function, the members of the associated anonymous type are automatically in scope in the body of the anonymous function.
  • 透過的な識別子を持つメンバーがスコープ内にある場合、そのメンバーのメンバーは、スコープもになります。When a member with a transparent identifier is in scope, the members of that member are in scope as well.
  • 透過的な識別子は、匿名オブジェクト初期化子のメンバー宣言子としてときに、透過的な識別子を持つメンバーが導入されています。When a transparent identifier occurs as a member declarator in an anonymous object initializer, it introduces a member with a transparent identifier.
  • 上記で説明した変換の手順で透過的な識別子は常に 1 つのオブジェクトのメンバーとして複数の範囲変数をキャプチャする目的で、匿名型と共に導入されました。In the translation steps described above, transparent identifiers are always introduced together with anonymous types, with the intent of capturing multiple range variables as members of a single object. C# の実装は、匿名型よりも、別のメカニズムを使用して、複数の範囲変数をグループ化する許可されます。An implementation of C# is permitted to use a different mechanism than anonymous types to group together multiple range variables. 次の変換の例には、匿名型を使用して透明度の識別子を表示することが前提としていますから変換できます。The following translation examples assume that anonymous types are used, and show how transparent identifiers can be translated away.

例では、The example

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }

変換されます。is translated into

from * in customers.
    SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }

これはさらに変換されます。which is further translated into

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(* => o.Total).
Select(* => new { c.Name, o.Total })

、透過的な識別子が消去されると、ときに、which, when transparent identifiers are erased, is equivalent to

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アクセスは、それ以外の場合、コンパイラによって生成された識別子です。where x is a compiler generated identifier that is otherwise invisible and inaccessible.

例では、The example

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 }

変換されます。is translated into

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 }

これはさらに縮小which is further reduced to

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 { *, p }).
Select(* => new { c.Name, o.OrderDate, p.ProductName })

最終的な変換は、します。the final translation of which is

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, p }).
Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })

場所xy、およびzは非表示とアクセスできない、それ以外の場合はコンパイラによって生成された識別子です。where x, y, and z are compiler generated identifiers that are otherwise invisible and inaccessible.

クエリ式パターンThe query expression pattern

クエリ式パターン型は、クエリ式をサポートするために実装できるメソッドのパターンを確立します。The Query expression pattern establishes a pattern of methods that types can implement to support query expressions. クエリ式は、構文のマップを使用して、メソッドの呼び出しに変換は、ために、かなり柔軟にクエリ式パターンを実装する方法がある型。Because query expressions are translated to method invocations by means of a syntactic mapping, types have considerable flexibility in how they implement the query expression pattern. たとえば、パターンのメソッド実装できますインスタンス メソッド、または拡張メソッドとして、2 つが、同じ呼び出し構文があるため、匿名関数は両方に変換するために、メソッドがデリゲートまたは式ツリーを要求できます。For example, the methods of the pattern can be implemented as instance methods or as extension methods because the two have the same invocation syntax, and the methods can request delegates or expression trees because anonymous functions are convertible to both.

ジェネリック型の推奨される図形C<T>をサポートする、クエリ式パターンを次に示します。The recommended shape of a generic type C<T> that supports the query expression pattern is shown below. ジェネリック型は、パラメーターと結果の型の間で、適切な関係を説明するために使用されますが、非ジェネリック型に同様のパターンを実装することは。A generic type is used in order to illustrate the proper relationships between parameter and result types, but it is possible to implement the pattern for non-generic types as well.

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>が、でした同様が他のデリゲートまたは式ツリー型と共に使用パラメーターと結果の種類で同じリレーションシップ。The methods above use the generic delegate types Func<T1,R> and Func<T1,T2,R>, but they could equally well have used other delegate or expression tree types with the same relationships in parameter and result types.

推奨の関係に注意してくださいC<T>O<T>を確実、ThenByThenByDescendingメソッドがの結果でのみ使用できますが、OrderByまたはOrderByDescendingします。Notice the recommended relationship between C<T> and O<T> which ensures that the ThenBy and ThenByDescending methods are available only on the result of an OrderBy or OrderByDescending. また、推奨される図形の結果のGroupBy--各内部シーケンスに追加して、シーケンスのシーケンスKeyプロパティ。Also notice the recommended shape of the result of GroupBy -- a sequence of sequences, where each inner sequence has an additional Key property.

System.Linq名前空間を実装する任意の型のクエリ演算子のパターンの実装を提供する、System.Collections.Generic.IEnumerable<T>インターフェイス。The System.Linq namespace provides an implementation of the query operator pattern for any type that implements the System.Collections.Generic.IEnumerable<T> interface.

代入演算子Assignment operators

代入演算子は、変数、プロパティ、イベント、またはインデクサーの要素を新しい値を割り当てます。The assignment operators assign a new value to a variable, a property, an event, or an indexer element.

assignment
    : unary_expression assignment_operator expression
    ;

assignment_operator
    : '='
    | '+='
    | '-='
    | '*='
    | '/='
    | '%='
    | '&='
    | '|='
    | '^='
    | '<<='
    | right_shift_assignment
    ;

代入式の左側のオペランドは、変数、プロパティ アクセス、インデクサー アクセス、またはイベント アクセスとして分類される式である必要があります。The left operand of an assignment must be an expression classified as a variable, a property access, an indexer access, or an event access.

=演算子が呼び出される、単純代入演算子します。The = operator is called the simple assignment operator. 左側のオペランドで指定されている変数、プロパティ、またはインデクサーの要素に右側のオペランドの値を割り当てます。It assigns the value of the right operand to the variable, property, or indexer element given by the left operand. 単純な代入演算子の左側のオペランドをイベント アクセスできない可能性があります (」に記載されていない限りフィールドのようなイベント)。The left operand of the simple assignment operator may not be an event access (except as described in Field-like events). 単純な代入演算子が記載単純な代入します。The simple assignment operator is described in Simple assignment.

以外の代入演算子、=演算子を呼び出す、複合代入演算子します。The assignment operators other than the = operator are called the compound assignment operators. これらの演算子は、2 つのオペランドで指定された操作を実行し、左側のオペランドで指定されている変数、プロパティ、またはインデクサーの要素に、結果の値を割り当てます。These operators perform the indicated operation on the two operands, and then assign the resulting value to the variable, property, or indexer element given by the left operand. 複合代入演算子が記載されて複合代入します。The compound assignment operators are described in Compound assignment.

+=-=イベントへのアクセス式で、左側のオペランドと演算子が呼び出されます、イベント代入演算子します。The += and -= operators with an event access expression as the left operand are called the event assignment operators. その他の代入演算子はありません、イベントのアクセス権を持つ有効な左側のオペランドとして。No other assignment operator is valid with an event access as the left operand. イベントの代入演算子が記載されてイベント割り当てします。The event assignment operators are described in Event assignment.

代入演算子が右から左の操作が右から左にまとめられていることを意味します。The assignment operators are right-associative, meaning that operations are grouped from right to left. たとえば、フォームの式a = b = cとして評価されますa = (b = c)します。For example, an expression of the form a = b = c is evaluated as a = (b = c).

単純代入Simple assignment

=演算子は、単純な代入演算子と呼ばれます。The = operator is called the simple assignment operator.

フォームの単純な代入の左辺のオペランドがE.PまたはE[Ei]場所Eコンパイル時の型を持つdynamic、割り当てが動的にバインドし、(動的バインド)。If the left operand of a simple assignment is of the form E.P or E[Ei] where E has the compile-time type dynamic, then the assignment is dynamically bound (Dynamic binding). この場合、代入式のコンパイル時の型はdynamicの実行時の型に基づいて実行時に以下に示す解決が行わEします。In this case the compile-time type of the assignment expression is dynamic, and the resolution described below will take place at run-time based on the run-time type of E.

単純な代入では、右側のオペランドが左のオペランドの型に暗黙的に変換する式必要があります。In a simple assignment, the right operand must be an expression that is implicitly convertible to the type of the left operand. 操作は、左側のオペランドで指定されている変数、プロパティ、またはインデクサーの要素を右側のオペランドの値を割り当てます。The operation assigns the value of the right operand to the variable, property, or indexer element given by the left operand.

単純な代入式の結果は、左側のオペランドに割り当てられている値です。The result of a simple assignment expression is the value assigned to the left operand. 結果は、左オペランドと同じ型を備え、値として常に分類されます。The result has the same type as the left operand and is always classified as a value.

左側のオペランドがプロパティまたはインデクサーのアクセスの場合は、プロパティまたはインデクサーがいる必要があります、setアクセサー。If the left operand is a property or indexer access, the property or indexer must have a set accessor. サポートしていない場合は、バインド時エラーが発生します。If this is not the case, a binding-time error occurs.

フォームの単純な割り当ての実行時の処理x = y次の手順で構成されています。The run-time processing of a simple assignment of the form x = y consists of the following steps:

  • 場合x変数として分類されます。If x is classified as a variable:
    • x 変数を生成するために評価されます。x is evaluated to produce the variable.
    • y 評価して、必要な場合、変換の型にx暗黙的な変換を行って (暗黙的な変換)。y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
    • 場合によって指定される変数xの配列要素である、 reference_typeの値を計算することを確認する実行時チェックが行われますyうち配列インスタンスとの互換性はxが、要素。If the variable given by x is an array element of a reference_type, a run-time check is performed to ensure that the value computed for y is compatible with the array instance of which x is an element. 場合、チェックは成功ynull、暗黙の参照変換の場合、または (暗黙の参照変換) 参照しているインスタンスの実際の型からが存在するy実際の要素の型に含んでいる配列インスタンスのxします。The check succeeds if y is null, or if an implicit reference conversion (Implicit reference conversions) exists from the actual type of the instance referenced by y to the actual element type of the array instance containing x. それ以外の場合は、System.ArrayTypeMismatchException がスローされます。Otherwise, a System.ArrayTypeMismatchException is thrown.
    • 評価との変換から得られた値yの評価によって指定された場所に格納されますxします。The value resulting from the evaluation and conversion of y is stored into the location given by the evaluation of x.
  • 場合xプロパティまたはインデクサーのアクセスに分類されます。If x is classified as a property or indexer access:
    • インスタンス式 (場合xないstatic) および引数リスト (場合xインデクサー アクセス) に関連付けられているxが評価されると、その後で、結果の使用setアクセサーの呼び出し。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent set accessor invocation.
    • y 評価して、必要な場合、変換の型にx暗黙的な変換を行って (暗黙的な変換)。y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
    • setのアクセサーxに対して計算された値で呼び出されるyとしてそのvalue引数。The set accessor of x is invoked with the value computed for y as its value argument.

配列の共変性規則 (配列の共変性) 配列型の値を許可A[]配列型のインスタンスへの参照であるB[]から暗黙の参照変換が存在する限り、BA.The array co-variance rules (Array covariance) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. これらの規則の配列要素への割り当てのため、 reference_type割り当てられている値が配列のインスタンスと互換性があることを確認する実行時チェックが必要です。Because of these rules, assignment to an array element of a reference_type requires a run-time check to ensure that the value being assigned is compatible with the array instance. In the example

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[]the last assignment causes a System.ArrayTypeMismatchException to be thrown because an instance of ArrayList cannot be stored in an element of a string[].

プロパティまたはインデクサーを宣言で、 struct_typeインスタンス式を代入式のターゲットに関連付けられているプロパティまたはインデクサー アクセスは、変数として分類する必要があります。When a property or indexer declared in a struct_type is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. インスタンス式が値として分類は、バインド時エラーが発生します。If the instance expression is classified as a value, a binding-time error occurs. ためメンバー アクセス、同じルールは、フィールドにも適用されます。Because of Member access, the same rule also applies to fields.

宣言があるとします。Given the declarations:

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; }
    }
}

in the example

Point p = new Point();
p.X = 100;
p.Y = 100;
Rectangle r = new Rectangle();
r.A = new Point(10, 10);
r.B = p;

割り当てp.Xp.Yr.A、およびr.Bので許可されますpr変数します。the assignments to p.X, p.Y, r.A, and r.B are permitted because p and r are variables. ただしの例However, in the example

Rectangle r = new Rectangle();
r.A.X = 10;
r.A.Y = 10;
r.B.X = 100;
r.B.Y = 100;

割り当ては、以降、すべての無効なr.Ar.B変数ではないです。the assignments are all invalid, since r.A and r.B are not variables.

複合代入。Compound assignment

フォームの複合代入の左辺のオペランドがE.PまたはE[Ei]場所Eコンパイル時の型を持つdynamic、割り当てが動的にバインドし、(動的バインド)。If the left operand of a compound assignment is of the form E.P or E[Ei] where E has the compile-time type dynamic, then the assignment is dynamically bound (Dynamic binding). この場合、代入式のコンパイル時の型はdynamicの実行時の型に基づいて実行時に以下に示す解決が行わEします。In this case the compile-time type of the assignment expression is dynamic, and the resolution described below will take place at run-time based on the run-time type of E.

フォームの操作をx op= y二項演算子のオーバー ロードの解決を適用することによって処理されます (二項演算子のオーバー ロードの解決)、操作が書き込まれた場合、x op yします。An operation of the form x op= y is processed by applying binary operator overload resolution (Binary operator overload resolution) as if the operation was written x op y. そうしたらThen,

  • 選択した演算子の戻り値の型がの型に暗黙的に変換できる場合はx、操作として評価されますx = x op yことを除いて、xは 1 回だけ評価されます。If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
  • それ以外の場合、選択した演算子の定義済みの演算子の型に明示的に変換できる場合は、選択した演算子の戻り値の型場合x、場合yの型に暗黙的に変換できるxまたは演算子が、演算子をシフトとして、操作が評価されますx = (T)(x op y)ここで、Tの型であるxことを除いて、xは 1 回だけ評価されます。Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.
  • それ以外の場合、複合代入が有効でないと、バインド エラーが発生します。Otherwise, the compound assignment is invalid, and a binding-time error occurs.

「1 回だけ評価」という用語では、ことを意味の評価でx op yの構成要素である式の結果x一時的に保存されからへの代入を実行するときに再使用xします。The term "evaluated only once" means that in the evaluation of x op y, the results of any constituent expressions of x are temporarily saved and then reused when performing the assignment to x. 割り当ての例では、A()[B()] += C()ここで、Aを返すメソッドは、 int[]、およびBCを返すメソッドint、メソッドは、順序で 1 回だけ呼び出されますAB, C.For example, in the assignment A()[B()] += C(), where A is a method returning int[], and B and C are methods returning int, the methods are invoked only once, in the order A, B, C.

プロパティまたはインデクサーが、両方にいる必要があります複合代入の左辺のオペランドは、プロパティ アクセスまたはインデクサーのアクセスには、ときに、getアクセサーとsetアクセサー。When the left operand of a compound assignment is a property access or indexer access, the property or indexer must have both a get accessor and a set accessor. サポートしていない場合は、バインド時エラーが発生します。If this is not the case, a binding-time error occurs.

前記の 2 番目のルールx op= yとして評価されるx = (T)(x op y)特定のコンテキストでします。The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. 定義済みの演算子の左側のオペランドの型はときに、複合演算子として使用できるように、ルールが存在するsbytebyteshortushort、またはcharします。