変換Conversions

A変換式を特定の型として扱うことができます。A conversion enables an expression to be treated as being of a particular type. 変換を別の種類を持つものとして扱う特定の型の式が発生する可能性があります。 または型を取得する型のない式があります。A conversion may cause an expression of a given type to be treated as having a different type, or it may cause an expression without a type to get a type. 変換暗黙的なまたは明示的な、および明示的なキャストが必要かどうかを指定します。Conversions can be implicit or explicit, and this determines whether an explicit cast is required. 型からの変換、int入力longが暗黙的な型の式をそのint型として暗黙的に処理できるlongFor instance, the conversion from type int to type long is implicit, so expressions of type int can implicitly be treated as type long. 型からの逆の変換long入力intは明示的なため、明示的なキャストが必要です。The opposite conversion, from type long to type int, is explicit and so an explicit cast is required.

int a = 123;
long b = a;         // implicit conversion from int to long
int c = (int) b;    // explicit conversion from long to int

一部の変換は言語によって定義されます。Some conversions are defined by the language. プログラムは、独自の型変換を定義も可能性があります (ユーザー定義の変換)。Programs may also define their own conversions (User-defined conversions).

暗黙の変換Implicit conversions

次の変換は、暗黙的な変換として分類されます。The following conversions are classified as implicit conversions:

  • 恒等変換Identity conversions
  • 暗黙的な数値変換Implicit numeric conversions
  • 列挙体の暗黙的な変換です。Implicit enumeration conversions.
  • Null 許容型の暗黙的な変換Implicit nullable conversions
  • Null リテラルの変換Null literal conversions
  • 暗黙的な参照変換Implicit reference conversions
  • ボックス化変換Boxing conversions
  • 動的の暗黙的な変換Implicit dynamic conversions
  • 定数式が暗黙的な変換Implicit constant expression conversions
  • ユーザー定義の暗黙的な変換User-defined implicit conversions
  • 匿名関数の変換Anonymous function conversions
  • メソッド グループ変換Method group conversions

暗黙的な変換は、さまざまな関数メンバーの呼び出しをなどの状況で発生することができます (コンパイル時の動的なオーバー ロードの解決チェック)、キャスト式 (キャスト式)、割り当て (代入演算子)。Implicit conversions can occur in a variety of situations, including function member invocations (Compile-time checking of dynamic overload resolution), cast expressions (Cast expressions), and assignments (Assignment operators).

定義済みの暗黙的な変換では、常に成功しがスローされる例外は発生しません。The pre-defined implicit conversions always succeed and never cause exceptions to be thrown. 適切にデザインされたユーザー定義の暗黙的な変換では、これらの特性もを示す必要があります。Properly designed user-defined implicit conversions should exhibit these characteristics as well.

型の変換のためのobjectdynamic同等と見なされます。For the purposes of conversion, the types object and dynamic are considered equivalent.

ただし、動的な変換 (動的の暗黙的な変換動的の明示的な変換) 型の式にのみ適用されますdynamic(動的な型).However, dynamic conversions (Implicit dynamic conversions and Explicit dynamic conversions) apply only to expressions of type dynamic (The dynamic type).

Id 変換Identity conversion

Id 変換は、任意の型から同じ型に変換します。An identity conversion converts from any type to the same type. この変換には、その型に変換可能であるエンティティを既に必要な型を持つことが言えますようにが存在します。This conversion exists such that an entity that already has a required type can be said to be convertible to that type.

  • objectdynamicと同等の間の id 変換があると見なされますobjectdynamic、間のすべての出現を置換するときに、同じ構築された型およびdynamicobject.Because object and dynamic are considered equivalent there is an identity conversion between object and dynamic, and between constructed types that are the same when replacing all occurrences of dynamic with object.

暗黙的な数値変換Implicit numeric conversions

暗黙的な数値変換は次のとおりです。The implicit numeric conversions are:

  • sbyteshortintlongfloatdouble、またはdecimalします。From sbyte to short, int, long, float, double, or decimal.
  • byteshortushortintuintlongulongfloatdouble、またはdecimalします。From byte to short, ushort, int, uint, long, ulong, float, double, or decimal.
  • shortintlongfloatdouble、またはdecimalします。From short to int, long, float, double, or decimal.
  • ushortintuintlongulongfloatdouble、またはdecimalします。From ushort to int, uint, long, ulong, float, double, or decimal.
  • intlongfloatdouble、またはdecimalします。From int to long, float, double, or decimal.
  • uintlongulongfloatdouble、またはdecimalします。From uint to long, ulong, float, double, or decimal.
  • longfloatdouble、またはdecimalします。From long to float, double, or decimal.
  • ulongfloatdouble、またはdecimalします。From ulong to float, double, or decimal.
  • charushortintuintlongulongfloatdouble、またはdecimalします。From char to ushort, int, uint, long, ulong, float, double, or decimal.
  • floatdoubleします。From float to double.

変換intuintlong、またはulongfloatとの間longまたはulongdoubleにより、有効桁数が失われる可能性がありますが、1 桁の損失しない原因は。Conversions from int, uint, long, or ulong to float and from long or ulong to double may cause a loss of precision, but will never cause a loss of magnitude. その他の暗黙的な数値変換情報は失われません。The other implicit numeric conversions never lose any information.

暗黙的な変換がない、char型であるために、その他の整数型の値は自動的に変換されない、char型。There are no implicit conversions to the char type, so values of the other integral types do not automatically convert to the char type.

列挙体の暗黙的な変換Implicit enumeration conversions

列挙体の暗黙的な変換を許可、 decimal_integer_literal 0いずれかに変換するenum_typeしにnullable_typeが基になる型は、 enum_typeします。An implicit enumeration conversion permits the decimal_integer_literal 0 to be converted to any enum_type and to any nullable_type whose underlying type is an enum_type. 後者の場合、変換は、基に変換することによって評価enum_type結果をラップし、(null 許容型)。In the latter case the conversion is evaluated by converting to the underlying enum_type and wrapping the result (Nullable types).

補間文字列の暗黙的な変換Implicit interpolated string conversions

暗黙の補間文字列変換により、 interpolated_string_expression (文字列補間) に変換するSystem.IFormattableまたはSystem.FormattableString(を実装するSystem.IFormattable).An implicit interpolated string conversion permits an interpolated_string_expression (Interpolated strings) to be converted to System.IFormattable or System.FormattableString (which implements System.IFormattable).

この変換が適用されるときに文字列値はありません補間文字列から構成されます。When this conversion is applied a string value is not composed from the interpolated string. 代わりに、インスタンスのSystem.FormattableString作成は、その詳細に説明文字列補間します。Instead an instance of System.FormattableString is created, as further described in Interpolated strings.

Null 許容型の暗黙的な変換Implicit nullable conversions

Null 非許容値型を操作する定義済みの暗黙的な変換は、これらの型の null 許容の形式でも使用できます。Predefined implicit conversions that operate on non-nullable value types can also be used with nullable forms of those types. 定義済みの暗黙的な id と null 非許容値型から変換する数値変換の各Snull 非許容値型にT、次の暗黙的な null 許容型の変換が存在します。For each of the predefined implicit identity and numeric conversions that convert from a non-nullable value type S to a non-nullable value type T, the following implicit nullable conversions exist:

  • 暗黙的な変換S?T?します。An implicit conversion from S? to T?.
  • 暗黙的な変換ST?します。An implicit conversion from S to T?.

Null 許容型の暗黙的な変換の評価がから基になる変換に基づくST次のように進みます。Evaluation of an implicit nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • 場合は、null 許容型の変換からS?T?:If the nullable conversion is from S? to T?:

    • 元の値が null の場合 (HasValueプロパティが false)、結果は、型の null 値T?します。If the source value is null (HasValue property is false), the result is the null value of type T?.
    • ラップ解除とそれ以外の場合、変換の評価はS?Sからの変換を基になると、その後ST、その後に、ラップ (null 許容型)からTT?します。Otherwise, the conversion is evaluated as an unwrapping from S? to S, followed by the underlying conversion from S to T, followed by a wrapping (Nullable types) from T to T?.
  • 場合は、null 許容型の変換からST?から基になる変換と変換の評価はSTからの折り返しを続けてTT?します。If the nullable conversion is from S to T?, the conversion is evaluated as the underlying conversion from S to T followed by a wrapping from T to T?.

Null リテラルの変換Null literal conversions

暗黙的な変換が存在する、nullリテラルを任意の null 許容型。An implicit conversion exists from the null literal to any nullable type. この変換には、null 値が生成されます (null 許容型) の指定された null 許容型。This conversion produces the null value (Nullable types) of the given nullable type.

暗黙的な参照変換Implicit reference conversions

暗黙の参照変換は次のとおりです。The implicit reference conversions are:

  • いずれかからreference_typeobjectdynamicします。From any reference_type to object and dynamic.
  • いずれかからclass_type Sいずれかにclass_type Tに用意されているSから派生Tします。From any class_type S to any class_type T, provided S is derived from T.
  • いずれかからclass_type Sいずれかにinterface_type Tに用意されているS実装Tします。From any class_type S to any interface_type T, provided S implements T.
  • いずれかからinterface_type Sいずれかにinterface_type Tに用意されているSから派生Tします。From any interface_type S to any interface_type T, provided S is derived from T.
  • Array_type S要素型がSEarray_type T要素型がTEtrue は、次のすべての提供。From an array_type S with an element type SE to an array_type T with an element type TE, provided all of the following are true:
    • S T要素の型のみが異なります。S and T differ only in element type. つまり、ST同じ次元数を持ちます。In other words, S and T have the same number of dimensions.
    • 両方SETEreference_type秒。Both SE and TE are reference_types.
    • 暗黙の参照変換が存在するSETEします。An implicit reference conversion exists from SE to TE.
  • いずれかからarray_typeSystem.Arrayとインターフェイスを実装します。From any array_type to System.Array and the interfaces it implements.
  • 1 次元配列型からS[]System.Collections.Generic.IList<T>とからの暗黙的な id または参照変換が提供される、基本インターフェイスSTします。From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces, provided that there is an implicit identity or reference conversion from S to T.
  • いずれかからdelegate_typeSystem.Delegateとインターフェイスを実装します。From any delegate_type to System.Delegate and the interfaces it implements.
  • いずれかに null リテラルからreference_typeします。From the null literal to any reference_type.
  • いずれかからreference_typereference_type Tへの暗黙的な id または参照変換がある場合、 reference_type T0T0が恒等変換をTします。From any reference_type to a reference_type T if it has an implicit identity or reference conversion to a reference_type T0 and T0 has an identity conversion to T.
  • いずれかからreference_type 、インターフェイスまたはデリゲート型にTインターフェイスまたはデリゲート型への暗黙的な id または参照変換がある場合T0T0(の差異に変換できるは分散変換) にTします。From any reference_type to an interface or delegate type T if it has an implicit identity or reference conversion to an interface or delegate type T0 and T0 is variance-convertible (Variance conversion) to T.
  • 使用する暗黙的な変換では、参照型にすることがわかっているパラメーターを入力します。Implicit conversions involving type parameters that are known to be reference types. 参照してください型パラメーターを使用する暗黙的な変換型パラメーターを使用する暗黙的な変換の詳細についてはします。See Implicit conversions involving type parameters for more details on implicit conversions involving type parameters.

暗黙の参照変換が変換の間でreference_typeを常に成功することが保証され、そのため、実行時のチェックは必要ありません。The implicit reference conversions are those conversions between reference_types that can be proven to always succeed, and therefore require no checks at run-time.

参照変換、暗黙的または明示的には、変換されるオブジェクトの参照 id を変更することはありません。Reference conversions, implicit or explicit, never change the referential identity of the object being converted. つまり、参照変換は、参照の種類を変更することが、変更しません、型または参照されるオブジェクトの値。In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.

ボックス化変換Boxing conversions

ボックス化変換では、 value_type参照型に暗黙的に変換します。A boxing conversion permits a value_type to be implicitly converted to a reference type. いずれかからボックス化変換が存在するnon_nullable_value_typeobjectdynamicSystem.ValueTypeしにinterface_typeによって実装される、 non_nullable_value_typeします。A boxing conversion exists from any non_nullable_value_type to object and dynamic, to System.ValueType and to any interface_type implemented by the non_nullable_value_type. さらに、 enum_type型に変換できるSystem.Enumします。Furthermore an enum_type can be converted to the type System.Enum.

ボックス化変換が存在する、 nullable_type 、参照型をボックス化変換場合にのみが存在する、基礎となるnon_nullable_value_type参照型にします。A boxing conversion exists from a nullable_type to a reference type, if and only if a boxing conversion exists from the underlying non_nullable_value_type to the reference type.

値の型がインターフェイス型にボックス化変換Iかどうかは、インターフェイス型にボックス化変換I0I0が恒等変換をIします。A value type has a boxing conversion to an interface type I if it has a boxing conversion to an interface type I0 and I0 has an identity conversion to I.

値の型がインターフェイス型にボックス化変換I、インターフェイスまたはデリゲート型にボックス化変換がある場合I0I0差異に変換できるは (分散変換)にI.A value type has a boxing conversion to an interface type I if it has a boxing conversion to an interface or delegate type I0 and I0 is variance-convertible (Variance conversion) to I.

値をボックス化、 non_nullable_value_typeオブジェクト インスタンスの割り当てとコピーから成る、 value_type値をそのインスタンスにします。Boxing a value of a non_nullable_value_type consists of allocating an object instance and copying the value_type value into that instance. 構造体は、型にボックス化されるSystem.ValueTypeすべての構造体の基本クラスでは、(継承)。A struct can be boxed to the type System.ValueType, since that is a base class for all structs (Inheritance).

値をボックス化、 nullable_type次のように進みます。Boxing a value of a nullable_type proceeds as follows:

  • 元の値が null の場合 (HasValueプロパティが false)、対象の型の参照を null になります。If the source value is null (HasValue property is false), the result is a null reference of the target type.
  • それ以外の場合、結果は、ボックス化されたへの参照をTラップの解除と、元の値をボックス化によって生成されました。Otherwise, the result is a reference to a boxed T produced by unwrapping and boxing the source value.

ボックス化変換の詳細についてはボックス化変換します。Boxing conversions are described further in Boxing conversions.

動的の暗黙的な変換Implicit dynamic conversions

型の式から動的の暗黙的な変換が存在するdynamic任意の型をTします。An implicit dynamic conversion exists from an expression of type dynamic to any type T. 変換が動的にバインドされている (動的バインド)、実行時に式の実行時の型からの暗黙的な変換が求められますことを意味するTします。The conversion is dynamically bound (Dynamic binding), which means that an implicit conversion will be sought at run-time from the run-time type of the expression to T. 変換が見つからない場合は、実行時に例外がスローされます。If no conversion is found, a run-time exception is thrown.

この暗黙の変換は、の先頭でアドバイスを一見違反に注意してください。暗黙的な変換暗黙的な変換では、例外は発生しません。Note that this implicit conversion seemingly violates the advice in the beginning of Implicit conversions that an implicit conversion should never cause an exception. ただしない自体には、変換が、検索の変換、例外が発生しました。However it is not the conversion itself, but the finding of the conversion that causes the exception. 実行時の例外のリスクは、動的バインドの使用に伴うです。The risk of run-time exceptions is inherent in the use of dynamic binding. 変換の動的バインドが望ましくない場合、式最初に変換できるobjectとし、目的の型。If dynamic binding of the conversion is not desired, the expression can be first converted to object, and then to the desired type.

次の例は、動的の暗黙的な変換を示しています。The following example illustrates implicit dynamic conversions:

object o  = "object"
dynamic d = "dynamic";

string s1 = o; // Fails at compile-time -- no conversion exists
string s2 = d; // Compiles and succeeds at run-time
int i     = d; // Compiles but fails at run-time -- no conversion exists

割り当てs2i両方で操作のバインディングが実行時まで中断されている、動的な暗黙的な変換を使用します。The assignments to s2 and i both employ implicit dynamic conversions, where the binding of the operations is suspended until run-time. 実行時の型から実行時に、暗黙的な変換のシークd -- string --ターゲットの型にします。At run-time, implicit conversions are sought from the run-time type of d -- string -- to the target type. 変換が検出されたstringにはintします。A conversion is found to string but not to int.

定数式が暗黙的な変換Implicit constant expression conversions

定数式が暗黙的な変換を次の変換を許可します。An implicit constant expression conversion permits the following conversions:

  • A constant_expression (定数式) 型のint型に変換できますsbytebyteshortushortuint、またはulongの値を提供、 constant_expressionが変換先の型の範囲内です。A constant_expression (Constant expressions) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant_expression is within the range of the destination type.
  • A constant_expression型のlong型に変換できますulongの値を提供、 constant_expressionが負でないです。A constant_expression of type long can be converted to type ulong, provided the value of the constant_expression is not negative.

型パラメーターを伴う暗黙の変換Implicit conversions involving type parameters

次の暗黙的な変換が特定の型パラメーターの存在T:The following implicit conversions exist for a given type parameter T:

  • T効果的な基底クラスにCからTの任意の基本クラスをCとの間Tによって実装されるインターフェイスを任意にCします。From T to its effective base class C, from T to any base class of C, and from T to any interface implemented by C. At 実行時に、ifT値の型は、ボックス化変換と変換を実行します。At run-time, if T is a value type, the conversion is executed as a boxing conversion. それ以外の場合、変換は暗黙的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • Tインターフェイス型にITの有効なインターフェイスのセットとの間Tの任意の基本インターフェイスをIします。From T to an interface type I in T's effective interface set and from T to any base interface of I. At 実行時に、ifT値の型は、ボックス化変換と変換を実行します。At run-time, if T is a value type, the conversion is executed as a boxing conversion. それ以外の場合、変換は暗黙的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • T型パラメーターにUに用意されているT異なりますU(パラメーターの制約入力)。From T to a type parameter U, provided T depends on U (Type parameter constraints). 実行時に、ifU値の型にはTU必ずしも同じ型では、変換は行われません。At run-time, if U is a value type, then T and U are necessarily the same type and no conversion is performed. の場合T値の型がボックス化変換と変換を実行します。Otherwise, if T is a value type, the conversion is executed as a boxing conversion. それ以外の場合、変換は暗黙的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • Null リテラルをからTに用意されているT参照型があることがわかっています。From the null literal to T, provided T is known to be a reference type.
  • T参照型にI参照型への暗黙的な変換があるかどうかはS0S0が恒等変換をSします。From T to a reference type I if it has an implicit conversion to a reference type S0 and S0 has an identity conversion to S. 実行時に、変換はへの変換と同様な実行S0します。At run-time the conversion is executed the same way as the conversion to S0.
  • Tインターフェイス型にIインターフェイスまたはデリゲート型への暗黙的な変換がある場合I0I0差異に変換できるにI(分散変換).From T to an interface type I if it has an implicit conversion to an interface or delegate type I0 and I0 is variance-convertible to I (Variance conversion). At 実行時に、ifT値の型は、ボックス化変換と変換を実行します。At run-time, if T is a value type, the conversion is executed as a boxing conversion. それ以外の場合、変換は暗黙的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.

場合T参照型がわかっている (パラメーターの制約入力)、上記の変換はすべて暗黙的な参照変換として分類 (暗黙の参照変換)。If T is known to be a reference type (Type parameter constraints), the conversions above are all classified as implicit reference conversions (Implicit reference conversions). 場合Tは上記の変換は参照型であるとわかっていない、ボックス化変換に分類されます (ボックス化変換)。If T is not known to be a reference type, the conversions above are classified as boxing conversions (Boxing conversions).

ユーザー定義の暗黙的な変換User-defined implicit conversions

省略可能な標準的な暗黙的な変換、省略可能な別の標準的な暗黙的な変換の後に、暗黙的な変換のユーザー定義演算子の実行後に、ユーザー定義の暗黙的な変換で構成されます。A user-defined implicit conversion consists of an optional standard implicit conversion, followed by execution of a user-defined implicit conversion operator, followed by another optional standard implicit conversion. ユーザー定義の暗黙的な変換を評価するための正確な規則については、「暗黙的な変換のユーザー定義の処理します。The exact rules for evaluating user-defined implicit conversions are described in Processing of user-defined implicit conversions.

匿名関数の変換とメソッド グループ変換Anonymous function conversions and method group conversions

匿名関数とメソッドのグループ自体の型がありませんが、デリゲート型または式ツリー型に暗黙的に変換可能性があります。Anonymous functions and method groups do not have types in and of themselves, but may be implicitly converted to delegate types or expression tree types. 匿名関数の変換がで詳しく説明されている匿名関数の変換とで、メソッド グループ変換メソッド グループ変換します。Anonymous function conversions are described in more detail in Anonymous function conversions and method group conversions in Method group conversions.

明示的な変換Explicit conversions

次の変換は、明示的な変換として分類されます。The following conversions are classified as explicit conversions:

  • すべての暗黙的な変換です。All implicit conversions.
  • 明示的な数値変換します。Explicit numeric conversions.
  • 明示的な列挙値の変換。Explicit enumeration conversions.
  • 明示的な null 許容変換します。Explicit nullable conversions.
  • 明示的な参照変換します。Explicit reference conversions.
  • 変換の明示的なインターフェイスです。Explicit interface conversions.
  • ボックス化解除変換します。Unboxing conversions.
  • 明示的な動的な変換Explicit dynamic conversions
  • ユーザー定義の明示的な変換です。User-defined explicit conversions.

明示的な変換はキャスト式で実行できます (キャスト式)。Explicit conversions can occur in cast expressions (Cast expressions).

明示的な変換のセットには、すべての暗黙的な変換が含まれています。The set of explicit conversions includes all implicit conversions. これは、冗長なキャスト式が許可されることを意味します。This means that redundant cast expressions are allowed.

暗黙的な変換ではない明示的な変換は、明示的なメリットを十分にさまざまな種類のドメイン間で変換を常に成功を証明することはできません、情報が失われる可能性があることがわかっている変換および変換表記法。The explicit conversions that are not implicit conversions are conversions that cannot be proven to always succeed, conversions that are known to possibly lose information, and conversions across domains of types sufficiently different to merit explicit notation.

明示的な数値変換Explicit numeric conversions

明示的な数値変換は、変換をnumeric_typenumeric_typeを暗黙的な数値変換 (暗黙的な数値変換)既に存在しません。The explicit numeric conversions are the conversions from a numeric_type to another numeric_type for which an implicit numeric conversion (Implicit numeric conversions) does not already exist:

  • sbytebyteushortuintulong、またはcharします。From sbyte to byte, ushort, uint, ulong, or char.
  • bytesbytecharします。From byte to sbyte and char.
  • shortsbytebyteushortuintulong、またはcharします。From short to sbyte, byte, ushort, uint, ulong, or char.
  • ushortsbytebyteshort、またはcharします。From ushort to sbyte, byte, short, or char.
  • intsbytebyteshortushortuintulong、またはcharします。From int to sbyte, byte, short, ushort, uint, ulong, or char.
  • uintsbytebyteshortushortint、またはcharします。From uint to sbyte, byte, short, ushort, int, or char.
  • longsbytebyteshortushortintuintulong、またはcharします。From long to sbyte, byte, short, ushort, int, uint, ulong, or char.
  • ulongsbytebyteshortushortintuintlong、またはcharします。From ulong to sbyte, byte, short, ushort, int, uint, long, or char.
  • charsbytebyte、またはshortします。From char to sbyte, byte, or short.
  • floatsbytebyteshortushortintuintlongulongchar、またはdecimalします。From float to sbyte, byte, short, ushort, int, uint, long, ulong, char, or decimal.
  • doublesbytebyteshortushortintuintlongulongcharfloat、またはdecimalします。From double to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or decimal.
  • decimalsbytebyteshortushortintuintlongulongcharfloat、またはdoubleします。From decimal to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double.

いずれかから変換することは常に明示的な変換では、すべての明示的および暗黙的な数値変換が含まれる、ためnumeric_typenumeric_typeキャスト式 (を使用します。キャスト式)。Because the explicit conversions include all implicit and explicit numeric conversions, it is always possible to convert from any numeric_type to any other numeric_type using a cast expression (Cast expressions).

明示的な数値変換では、情報が失われる可能性がありますかがスローされる例外が発生する可能性があります。The explicit numeric conversions possibly lose information or possibly cause exceptions to be thrown. 明示的な数値変換は、次のように処理されます。An explicit numeric conversion is processed as follows:

  • 整数型から別の整数型への変換では、処理は、オーバーフロー チェック コンテキストに依存 (checked と unchecked 演算子) 移動変換では、配置します。For a conversion from an integral type to another integral type, the processing depends on the overflow checking context (The checked and unchecked operators) in which the conversion takes place:
    • checkedコンテキスト、ソース オペランドの値が変換先の型の範囲内にもスローする場合、変換に成功した、System.OverflowExceptionソース オペランドの値が変換先の型の範囲外にある場合。In a checked context, the conversion succeeds if the value of the source operand is within the range of the destination type, but throws a System.OverflowException if the value of the source operand is outside the range of the destination type.
    • uncheckedコンテキスト変換常に成功し、次のように進みます。In an unchecked context, the conversion always succeeds, and proceeds as follows.
      • 変換元の型が変換先の型より大きい場合、変換元の値はその "余分な" 最上位ビットを破棄することで切り詰められます。If the source type is larger than the destination type, then the source value is truncated by discarding its "extra" most significant bits. 結果は変換先の型の値として扱われます。The result is then treated as a value of the destination type.
      • 変換元の型が変換先の型より小さい場合、変換元の値は変換先の型と同じサイズになるように符号かゼロが拡張されます。If the source type is smaller than the destination type, then the source value is either sign-extended or zero-extended so that it is the same size as the destination type. 変換元の型に符号が付いている場合は符号拡張が利用され、符号が付いていない場合はゼロ拡張が利用されます。Sign-extension is used if the source type is signed; zero-extension is used if the source type is unsigned. 結果は変換先の型の値として扱われます。The result is then treated as a value of the destination type.
      • 変換元の型が変換先の型と同じサイズの場合、変換元の値は変換先の型の値として扱われます。If the source type is the same size as the destination type, then the source value is treated as a value of the destination type.
  • 変換のdecimal、整数型にソース値が最も近い整数値を 0 方向に丸められ、この整数値の変換の結果になります。For a conversion from decimal to an integral type, the source value is rounded towards zero to the nearest integral value, and this integral value becomes the result of the conversion. 結果の整数値が変換先の型の範囲外の場合、System.OverflowExceptionがスローされます。If the resulting integral value is outside the range of the destination type, a System.OverflowException is thrown.
  • 変換のfloatまたはdoubleを整数型、処理は、オーバーフロー チェック コンテキストに依存 (checked と unchecked 演算子) 変換が、配置。For a conversion from float or double to an integral type, the processing depends on the overflow checking context (The checked and unchecked operators) in which the conversion takes place:
    • checkedコンテキスト、変換処理次のようにします。In a checked context, the conversion proceeds as follows:
      • オペランドの値が NaN、無限、またはの場合、System.OverflowExceptionがスローされます。If the value of the operand is NaN or infinite, a System.OverflowException is thrown.
      • それ以外の場合、ソース オペランドは最も近い整数値を 0 方向に丸められます。Otherwise, the source operand is rounded towards zero to the nearest integral value. 場合、この整数値を変換先の型の範囲内でこの値は変換の結果です。If this integral value is within the range of the destination type then this value is the result of the conversion.
      • それ以外の場合は、System.OverflowException がスローされます。Otherwise, a System.OverflowException is thrown.
    • uncheckedコンテキスト変換常に成功し、次のように進みます。In an unchecked context, the conversion always succeeds, and proceeds as follows.
      • オペランドの値が NaN、無限の変換の結果は、変換先の型の値が指定されていない場合。If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type.
      • それ以外の場合、ソース オペランドは最も近い整数値を 0 方向に丸められます。Otherwise, the source operand is rounded towards zero to the nearest integral value. 場合、この整数値を変換先の型の範囲内でこの値は変換の結果です。If this integral value is within the range of the destination type then this value is the result of the conversion.
      • それ以外の場合、変換の結果は、先の型の値は指定されません。Otherwise, the result of the conversion is an unspecified value of the destination type.
  • 変換のdoublefloatdouble値に丸められます、最も近いfloat値。For a conversion from double to float, the double value is rounded to the nearest float value. 場合、doubleとして表す値が小さすぎる、float結果が正のゼロまたは負のゼロ。If the double value is too small to represent as a float, the result becomes positive zero or negative zero. 場合、doubleとして表す値が大きすぎて、float結果は正の無限大または負の無限大になります。If the double value is too large to represent as a float, the result becomes positive infinity or negative infinity. 場合、double値が NaN の結果は、NaN ではも場合、します。If the double value is NaN, the result is also NaN.
  • 変換のfloatまたはdoubledecimal、ソース値に変換されますdecimal表現し、必要な場合、28 小数点後近似値に丸められます (10 進数型).For a conversion from float or double to decimal, the source value is converted to decimal representation and rounded to the nearest number after the 28th decimal place if required (The decimal type). ソース値が小さすぎてとして表すかどうか、decimal結果はゼロになります。If the source value is too small to represent as a decimal, the result becomes zero. 場合、元の値が NaN の場合、無限大、または大きすぎてとして表す、 decimalSystem.OverflowExceptionがスローされます。If the source value is NaN, infinity, or too large to represent as a decimal, a System.OverflowException is thrown.
  • 変換のdecimalfloatまたはdoubledecimal値に丸められます、最も近いdoubleまたはfloat値。For a conversion from decimal to float or double, the decimal value is rounded to the nearest double or float value. この変換は、有効桁数を失う可能性があります、中には、ことはありませんがスローされる例外が発生します。While this conversion may lose precision, it never causes an exception to be thrown.

明示的な列挙値の変換Explicit enumeration conversions

明示的な列挙値の変換は次のとおりです。The explicit enumeration conversions are:

  • sbytebyteshortushortintuintlongulongcharfloatdouble、またはdecimal任意にenum_typeします。From sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, or decimal to any enum_type.
  • いずれかからenum_typesbytebyteshortushortintuintlongulongcharfloatdouble、またはdecimalします。From any enum_type to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, or decimal.
  • いずれかからenum_typeenum_typeします。From any enum_type to any other enum_type.

2 つの型の間の明示的な列挙型変換が任意参加を扱うことにより処理されるenum_typeを基になる型としてenum_type、してから、暗黙的または明示的なを実行します。結果として得られる型間の数値変換します。An explicit enumeration conversion between two types is processed by treating any participating enum_type as the underlying type of that enum_type, and then performing an implicit or explicit numeric conversion between the resulting types. たとえば、 enum_type Eでの種類を基になるとintからの変換Ebyte明示的な数値変換として処理されます (明示的な数値変換) からintbyteからの変換とbyteE暗黙的な数値変換として処理されます (暗黙的な数値変換)byteintします。For example, given an enum_type E with and underlying type of int, a conversion from E to byte is processed as an explicit numeric conversion (Explicit numeric conversions) from int to byte, and a conversion from byte to E is processed as an implicit numeric conversion (Implicit numeric conversions) from byte to int.

明示的な null 許容型の変換Explicit nullable conversions

明示的な null 許容変換定義済みの型の null 許容の形式でも使用する null 非許容値型を操作する明示的な変換を許可します。Explicit nullable conversions permit predefined explicit conversions that operate on non-nullable value types to also be used with nullable forms of those types. Null 非許容値型から変換する定義済みの明示的な変換の各Snull 非許容値型にT(恒等変換暗黙的な数値変換列挙体の暗黙的な変換明示的な数値変換、および列挙値の明示的な変換)、以下null 許容型の変換が存在します。For each of the predefined explicit conversions that convert from a non-nullable value type S to a non-nullable value type T (Identity conversion, Implicit numeric conversions, Implicit enumeration conversions, Explicit numeric conversions, and Explicit enumeration conversions), the following nullable conversions exist:

  • 明示的な変換をS?T?します。An explicit conversion from S? to T?.
  • 明示的な変換をST?します。An explicit conversion from S to T?.
  • 明示的な変換をS?Tします。An explicit conversion from S? to T.

Null 許容型の変換の評価がから基になる変換に基づくST次のように進みます。Evaluation of a nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • 場合は、null 許容型の変換からS?T?:If the nullable conversion is from S? to T?:
    • 元の値が null の場合 (HasValueプロパティが false)、結果は、型の null 値T?します。If the source value is null (HasValue property is false), the result is the null value of type T?.
    • ラップ解除とそれ以外の場合、変換の評価はS?Sからの変換を基になると、その後ST、その後に、ラップをからTT?します。Otherwise, the conversion is evaluated as an unwrapping from S? to S, followed by the underlying conversion from S to T, followed by a wrapping from T to T?.
  • 場合は、null 許容型の変換からST?から基になる変換と変換の評価はSTからの折り返しを続けてTT?します。If the nullable conversion is from S to T?, the conversion is evaluated as the underlying conversion from S to T followed by a wrapping from T to T?.
  • 場合は、null 許容型の変換からS?Tからラップ解除すると、変換の評価はS?Sから基になる変換STIf the nullable conversion is from S? to T, the conversion is evaluated as an unwrapping from S? to S followed by the underlying conversion from S to T.

値の場合、null 許容値のラップを解除しようとするは例外をスローことに注意してください。nullします。Note that an attempt to unwrap a nullable value will throw an exception if the value is null.

明示的な参照変換Explicit reference conversions

明示的な参照変換は次のとおりです。The explicit reference conversions are:

  • objectdynamicreference_typeします。From object and dynamic to any other reference_type.
  • いずれかからclass_type Sいずれかにclass_type Tに用意されているSの基本クラスであるTします。From any class_type S to any class_type T, provided S is a base class of T.
  • いずれかからclass_type Sいずれかにinterface_type Tに用意されているSシールおよび提供されないS実装しないTします。From any class_type S to any interface_type T, provided S is not sealed and provided S does not implement T.
  • いずれかからinterface_type Sいずれかにclass_type Tに用意されているTシールまたは指定されていないT実装Sします。From any interface_type S to any class_type T, provided T is not sealed or provided T implements S.
  • いずれかからinterface_type Sいずれかにinterface_type Tに用意されているSから派生していないTします。From any interface_type S to any interface_type T, provided S is not derived from T.
  • Array_type S要素型がSEarray_type T要素型がTEtrue は、次のすべての提供。From an array_type S with an element type SE to an array_type T with an element type TE, provided all of the following are true:
    • S T要素の型のみが異なります。S and T differ only in element type. つまり、ST同じ次元数を持ちます。In other words, S and T have the same number of dimensions.
    • 両方SETEreference_type秒。Both SE and TE are reference_types.
    • 明示的な参照変換が存在するSETEします。An explicit reference conversion exists from SE to TE.
  • System.Arrayいずれかに、インターフェイスを実装およびarray_typeします。From System.Array and the interfaces it implements to any array_type.
  • 1 次元配列型からS[]System.Collections.Generic.IList<T>とからの明示的な参照変換が提供される、基本インターフェイスSTします。From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces, provided that there is an explicit reference conversion from S to T.
  • System.Collections.Generic.IList<S> 1 次元の配列型をその基本インターフェイスとT[]からの明示的な id または参照変換はそのSTします。From System.Collections.Generic.IList<S> and its base interfaces to a single-dimensional array type T[], provided that there is an explicit identity or reference conversion from S to T.
  • System.Delegateいずれかに、インターフェイスを実装およびdelegate_typeします。From System.Delegate and the interfaces it implements to any delegate_type.
  • 参照型への参照型からT参照型への明示的な参照変換があるかどうかはT0T0が恒等変換Tします。From a reference type to a reference type T if it has an explicit reference conversion to a reference type T0 and T0 has an identity conversion T.
  • インターフェイスまたはデリゲートの型への参照型からTインターフェイスまたはデリゲート型への明示的な参照変換がある場合T0T0差異に変換できるにTまたはTは変換できる分散T0(分散変換)。From a reference type to an interface or delegate type T if it has an explicit reference conversion to an interface or delegate type T0 and either T0 is variance-convertible to T or T is variance-convertible to T0 (Variance conversion).
  • D<S1...Sn>D<T1...Tn>場所D<X1...Xn>が汎用デリゲート型では、D<S1...Sn>と互換性があるかと同じでないD<T1...Tn>、およびそれぞれの型パラメーターXiD次の保留。From D<S1...Sn> to D<T1...Tn> where D<X1...Xn> is a generic delegate type, D<S1...Sn> is not compatible with or identical to D<T1...Tn>, and for each type parameter Xi of D the following holds:
    • 場合XiしバリアントではSiヲェヒェケェ ・Tiします。If Xi is invariant, then Si is identical to Ti.
    • 場合Xi共変性を持つ、暗黙的または明示的な id または参照からの変換はSiTiIf Xi is covariant, then there is an implicit or explicit identity or reference conversion from Si to Ti.
    • 場合Xiは反変、SiTiは同一と両方の参照型。If Xi is contravariant, then Si and Ti are either identical or both reference types.
  • 使用する明示的な変換では、参照型にすることがわかっているパラメーターを入力します。Explicit conversions involving type parameters that are known to be reference types. 型パラメーターを使用する明示的な変換の詳細については、次を参照してください。型パラメーターを使用する明示的な変換します。For more details on explicit conversions involving type parameters, see Explicit conversions involving type parameters.

明示的な参照変換は、実行時のチェックが正しいことを確認を必要とする参照型の間で変換のことです。The explicit reference conversions are those conversions between reference-types that require run-time checks to ensure they are correct.

明示的な参照変換を実行時に正常にするには、ソース オペランドの値がある必要がありますnull、またはソース オペランドによって参照されるオブジェクトの実際の型の暗黙的な参照によって変換先の型に変換できる型でなければなりません変換 (暗黙の参照変換) またはボックス化変換 (ボックス化変換)。For an explicit reference conversion to succeed at run-time, the value of the source operand must be null, or the actual type of the object referenced by the source operand must be a type that can be converted to the destination type by an implicit reference conversion (Implicit reference conversions) or boxing conversion (Boxing conversions). 明示的な参照変換に失敗した場合、System.InvalidCastExceptionがスローされます。If an explicit reference conversion fails, a System.InvalidCastException is thrown.

参照変換、暗黙的または明示的には、変換されるオブジェクトの参照 id を変更することはありません。Reference conversions, implicit or explicit, never change the referential identity of the object being converted. つまり、参照変換は、参照の種類を変更することが、変更しません、型または参照されるオブジェクトの値。In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.

ボックス化解除変換Unboxing conversions

ボックス化解除の変換では参照型に明示的に変換する、 value_typeします。An unboxing conversion permits a reference type to be explicitly converted to a value_type. 型からボックス化解除の変換が存在するobjectdynamicSystem.ValueTypeいずれかにnon_nullable_value_type、いずれかからinterface_typeいずれかにnon_nullable_value_typeを実装する、 interface_typeします。An unboxing conversion exists from the types object, dynamic and System.ValueType to any non_nullable_value_type, and from any interface_type to any non_nullable_value_type that implements the interface_type. さらに入力System.Enumいずれかにボックス化解除できますenum_typeします。Furthermore type System.Enum can be unboxed to any enum_type.

参照型をボックス化解除の変換が存在する、 nullable_type 、基になる参照型のアンボックス変換が存在する場合はnon_nullable_value_typenullable_typeします。An unboxing conversion exists from a reference type to a nullable_type if an unboxing conversion exists from the reference type to the underlying non_nullable_value_type of the nullable_type.

値型Sがインターフェイス型型からをボックス化解除変換Iインターフェイス型型からのボックス化解除の変換があるかどうかはI0I0が恒等変換をIします。A value type S has an unboxing conversion from an interface type I if it has an unboxing conversion from an interface type I0 and I0 has an identity conversion to I.

値型Sがインターフェイス型型からをボックス化解除変換Iインターフェイスまたはデリゲートの型からボックス化解除の変換がある場合I0I0差異に変換できるにIまたはI差異に変換できるにI0(分散変換)。A value type S has an unboxing conversion from an interface type I if it has an unboxing conversion from an interface or delegate type I0 and either I0 is variance-convertible to I or I is variance-convertible to I0 (Variance conversion).

ボックス化解除の操作は、オブジェクトのインスタンスのボックス化された値は、最初に確認の指定されたvalue_type、し、そのインスタンスから値をコピーします。An unboxing operation consists of first checking that the object instance is a boxed value of the given value_type, and then copying the value out of the instance. Null 参照がボックス化解除、 nullable_typeの null 値を生成、 nullable_typeします。Unboxing a null reference to a nullable_type produces the null value of the nullable_type. 構造体の型からボックス化が解除できますSystem.ValueTypeすべての構造体の基本クラスでは、(継承)。A struct can be unboxed from the type System.ValueType, since that is a base class for all structs (Inheritance).

ボックス化解除変換の詳細についてはボックス化解除変換します。Unboxing conversions are described further in Unboxing conversions.

明示的な動的な変換Explicit dynamic conversions

型の式から動的の明示的な変換が存在するdynamic任意の型をTします。An explicit dynamic conversion exists from an expression of type dynamic to any type T. 変換が動的にバインドされている (動的バインド)、つまり、実行時に式の実行時の型からの明示的な変換が求められますことTします。The conversion is dynamically bound (Dynamic binding), which means that an explicit conversion will be sought at run-time from the run-time type of the expression to T. 変換が見つからない場合は、実行時に例外がスローされます。If no conversion is found, a run-time exception is thrown.

変換の動的バインドが望ましくない場合、式最初に変換できるobjectとし、目的の型。If dynamic binding of the conversion is not desired, the expression can be first converted to object, and then to the desired type.

次のクラスが定義されていると仮定します。Assume the following class is defined:

class C
{
    int i;

    public C(int i) { this.i = i; }

    public static explicit operator C(string s) 
    {
        return new C(int.Parse(s));
    }
}

次の例は、明示的な動的な変換を示しています。The following example illustrates explicit dynamic conversions:

object o  = "1";
dynamic d = "2";

var c1 = (C)o; // Compiles, but explicit reference conversion fails
var c2 = (C)d; // Compiles and user defined conversion succeeds

最適な変換oCが記載された明示的な参照変換をコンパイルします。The best conversion of o to C is found at compile-time to be an explicit reference conversion. に、実行時に、これが失敗した"1"ファクトでは、Cします。This fails at run-time, because "1" is not in fact a C. 変換dC実行時、ユーザーがの実行時の型からの変換を定義するが、明示的な動的変換としてがただし、中断されてd -- string --にCが見つかると、成功したとします。The conversion of d to C however, as an explicit dynamic conversion, is suspended to run-time, where a user defined conversion from the run-time type of d -- string -- to C is found, and succeeds.

型パラメーターを使用する明示的な変換Explicit conversions involving type parameters

次の明示的な変換が指定された型パラメーターの存在T:The following explicit conversions exist for a given type parameter T:

  • 有効な基本クラスからCTTとの任意の基本クラスからCTします。From the effective base class C of T to T and from any base class of C to T. 実行時に、ifT値型である、変換、アンボックス変換として実行します。At run-time, if T is a value type, the conversion is executed as an unboxing conversion. それ以外の場合、変換は、明示的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • 任意のインターフェイス型からTします。From any interface type to T. 実行時に、ifT値型である、変換、アンボックス変換として実行します。At run-time, if T is a value type, the conversion is executed as an unboxing conversion. それ以外の場合、変換は、明示的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • Tいずれかにinterface_type I既にからの暗黙的な変換がないTIします。From T to any interface_type I provided there is not already an implicit conversion from T to I. 実行時に、ifT値型である明示的な参照変換の後にボックス化変換と変換を実行します。At run-time, if T is a value type, the conversion is executed as a boxing conversion followed by an explicit reference conversion. それ以外の場合、変換は、明示的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • 型パラメーターからUTに用意されているT異なりますU(パラメーターの制約入力)。From a type parameter U to T, provided T depends on U (Type parameter constraints). 実行時に、ifU値の型にはTU必ずしも同じ型では、変換は行われません。At run-time, if U is a value type, then T and U are necessarily the same type and no conversion is performed. の場合T値型である、変換、アンボックス変換として実行します。Otherwise, if T is a value type, the conversion is executed as an unboxing conversion. それ以外の場合、変換は、明示的な参照変換または id 変換として実行されます。Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.

場合Tはわかっていますが、参照型である、上記の変換はすべてとして分類明示的な参照変換 (明示的な参照変換)。If T is known to be a reference type, the conversions above are all classified as explicit reference conversions (Explicit reference conversions). 場合Tは上記の変換は参照型であるとわかっていない、ボックス化解除変換に分類されます (ボックス化解除変換)。If T is not known to be a reference type, the conversions above are classified as unboxing conversions (Unboxing conversions).

上記の規則は、制約のない型パラメーターから、インターフェイスではない型への直接明示的な変換許可されていません驚くべきことが必要があります。The above rules do not permit a direct explicit conversion from an unconstrained type parameter to a non-interface type, which might be surprising. このルールの理由は、このような変換をオフのセマンティクスを混乱を避けるためです。The reason for this rule is to prevent confusion and make the semantics of such conversions clear. たとえば、次のような宣言があるとします。For example, consider the following declaration:

class X<T>
{
    public static long F(T t) {
        return (long)t;                // Error 
    }
}

場合の直接の明示的な変換tintが許可されているいずれかが簡単に期待するX<int>.F(7)を返します 7LIf the direct explicit conversion of t to int were permitted, one might easily expect that X<int>.F(7) would return 7L. ただし、設定されませんでしたが、標準の数値の変換は、バインド時に数値型がわかっている場合にのみと見なされるためです。However, it would not, because the standard numeric conversions are only considered when the types are known to be numeric at binding-time. セマンティクスを作成するには明確で上記の例では、代わりに記述する必要があります。In order to make the semantics clear, the above example must instead be written:

class X<T>
{
    public static long F(T t) {
        return (long)(object)t;        // Ok, but will only work when T is long
    }
}

このコードはコンパイルされますが、実行時X<int>.F(7)ボックス化された後の実行時に、例外をスローしはintに直接変換することはできません、longします。This code will now compile but executing X<int>.F(7) would then throw an exception at run-time, since a boxed int cannot be converted directly to a long.

ユーザー定義の明示的な変換User-defined explicit conversions

ユーザー定義の明示的な変換は、省略可能な標準的な明示的な変換後に省略可能な別の標準的な明示的な変換の後に、ユーザー定義の暗黙的または明示的な変換演算子の実行で構成されます。A user-defined explicit conversion consists of an optional standard explicit conversion, followed by execution of a user-defined implicit or explicit conversion operator, followed by another optional standard explicit conversion. ユーザー定義の明示的な変換を評価するための正確な規則については、「明示的な変換のユーザー定義の処理します。The exact rules for evaluating user-defined explicit conversions are described in Processing of user-defined explicit conversions.

標準変換Standard conversions

標準の変換は、ユーザー定義の変換の一部として発生する変換の定義済みです。The standard conversions are those pre-defined conversions that can occur as part of a user-defined conversion.

標準の暗黙的な変換Standard implicit conversions

次の暗黙的な変換は、標準の暗黙的な変換として分類されます。The following implicit conversions are classified as standard implicit conversions:

具体的には、標準の暗黙的な変換は、ユーザー定義の暗黙的な変換を除外します。The standard implicit conversions specifically exclude user-defined implicit conversions.

標準の明示的な変換Standard explicit conversions

標準の明示的な変換は、すべての標準的な暗黙的な変換と反対の標準的な暗黙的な変換が存在する明示的な変換のサブセットです。The standard explicit conversions are all standard implicit conversions plus the subset of the explicit conversions for which an opposite standard implicit conversion exists. つまり、標準の暗黙的な変換が存在する場合、型からA型にB、型から標準の明示的な変換が存在し、A入力B型との間B入力AIn other words, if a standard implicit conversion exists from a type A to a type B, then a standard explicit conversion exists from type A to type B and from type B to type A.

ユーザー定義の変換User-defined conversions

C# では、事前に定義された明示的および暗黙的な変換を拡張してユーザー定義の変換します。C# allows the pre-defined implicit and explicit conversions to be augmented by user-defined conversions. ユーザー定義の変換が変換演算子を宣言することで導入されました (変換演算子) クラスと構造体の型。User-defined conversions are introduced by declaring conversion operators (Conversion operators) in class and struct types.

ユーザー定義の変換を許可Permitted user-defined conversions

C# でのみ特定のユーザー定義変換を宣言します。C# permits only certain user-defined conversions to be declared. 具体的には、既存の暗黙的または明示的な変換を再定義することはできません。In particular, it is not possible to redefine an already existing implicit or explicit conversion.

指定したソースの種類Sターゲットの種類とT場合は、SまたはTは null 許容型は、ようにS0T0それ以外の場合、基になる型を参照してくださいS0T0は等しいSTそれぞれします。For a given source type S and target type T, if S or T are nullable types, let S0 and T0 refer to their underlying types, otherwise S0 and T0 are equal to S and T respectively. ソースの種類からの変換を宣言するクラスまたは構造体が許可されているSをターゲットの型T次のすべてに当てはまる場合にのみ。A class or struct is permitted to declare a conversion from a source type S to a target type T only if all of the following are true:

  • S0 T0はさまざまな種類。S0 and T0 are different types.
  • いずれかS0またはT0演算子宣言が行われるクラスまたは構造体の型です。Either S0 or T0 is the class or struct type in which the operator declaration takes place.
  • どちらもS0T0は、 interface_typeします。Neither S0 nor T0 is an interface_type.
  • ユーザー定義の変換を除く、変換が存在しないからSTまたはからTSします。Excluding user-defined conversions, a conversion does not exist from S to T or from T to S.

ユーザー定義の変換に適用される制限については、説明でさらに変換演算子します。The restrictions that apply to user-defined conversions are discussed further in Conversion operators.

リフト変換演算子Lifted conversion operators

Null 非許容値型に変換するユーザー定義の変換演算子を指定されたSnull 非許容値型にT変換演算子のリフトから変換が存在するS?T?.Given a user-defined conversion operator that converts from a non-nullable value type S to a non-nullable value type T, a lifted conversion operator exists that converts from S? to T?. ラップ解除、このリフト変換演算子を実行しますS?Sからユーザー定義の変換後にSTからの折り返しを続けてTT?点を除き、null値を持つS?値は null に直接変換T?します。This lifted conversion operator performs an unwrapping from S? to S followed by the user-defined conversion from S to T followed by a wrapping from T to T?, except that a null valued S? converts directly to a null valued T?.

リフト変換演算子が、その基になるユーザー定義の変換演算子として同じ暗黙的または明示的な分類します。A lifted conversion operator has the same implicit or explicit classification as its underlying user-defined conversion operator. 「ユーザー定義の変換」は、両方の使用に適用期間は、ユーザー定義し、リフト変換演算子。The term "user-defined conversion" applies to the use of both user-defined and lifted conversion operators.

ユーザー定義の変換の評価Evaluation of user-defined conversions

ユーザー定義の変換と呼ばれる、その型からの値の変換、ソースの種類、という名前の別の型に、ターゲットの種類します。A user-defined conversion converts a value from its type, called the source type, to another type, called the target type. ユーザー定義の変換の評価を確認する方法に中央揃え、最も具体的特定のソースとターゲットの種類のユーザー定義変換演算子。Evaluation of a user-defined conversion centers on finding the most specific user-defined conversion operator for the particular source and target types. この決定は、いくつかの手順に分かれています。This determination is broken into several steps:

  • クラスと元のユーザー定義の変換演算子を考慮する構造体のセットを検索します。Finding the set of classes and structs from which user-defined conversion operators will be considered. このセットは、ソースの種類とその基本クラスとターゲットの種類 (クラスと構造体のみがユーザー定義の演算子を宣言でき、クラス以外の型が基底クラスを含むなしの暗黙の想定) をその基本クラスで構成されます。This set consists of the source type and its base classes and the target type and its base classes (with the implicit assumptions that only classes and structs can declare user-defined operators, and that non-class types have no base classes). ソースまたはターゲットのいずれかの型がある場合、この手順の目的で、 nullable_type、その基になる型は代わりに使用されます。For the purposes of this step, if either the source or target type is a nullable_type, their underlying type is used instead.
  • 型が設定されるユーザー定義して、リフト変換演算子の決定に適用されます。From that set of types, determining which user-defined and lifted conversion operators are applicable. 変換演算子を適用する場合にの標準変換を実行する場合があります (標準変換) オペランドのソースの種類からは、演算子の種類で標準変換を実行できる必要があります対象の型に演算子の結果の型。For a conversion operator to be applicable, it must be possible to perform a standard conversion (Standard conversions) from the source type to the operand type of the operator, and it must be possible to perform a standard conversion from the result type of the operator to the target type.
  • 該当するユーザー定義演算子のセットからには、演算子が明確に最も固有を決定します。From the set of applicable user-defined operators, determining which operator is unambiguously the most specific. 一般的な用語では、最も固有の演算子はオペランドの型がソースの種類に「最も近い」で、結果の型は、ターゲット型に「最も近い」演算子が。In general terms, the most specific operator is the operator whose operand type is "closest" to the source type and whose result type is "closest" to the target type. ユーザー定義変換演算子は、リフト変換演算子より優先されます。User-defined conversion operators are preferred over lifted conversion operators. 最も固有のユーザー定義変換演算子を確立するための正確な規則は、次のセクションで定義されます。The exact rules for establishing the most specific user-defined conversion operator are defined in the following sections.

特定のユーザー定義の変換演算子が識別されると、ユーザー定義の変換の実際の実行に最大 3 つの手順が含まれます。Once a most specific user-defined conversion operator has been identified, the actual execution of the user-defined conversion involves up to three steps:

  • 最初に、必要な場合は、ソースの種類から、またはユーザー定義の変換の変換演算子のオペランドの型への標準変換を実行します。First, if required, performing a standard conversion from the source type to the operand type of the user-defined or lifted conversion operator.
  • 次に、変換を実行するユーザー定義またはリフトの変換演算子を呼び出しています。Next, invoking the user-defined or lifted conversion operator to perform the conversion.
  • 最後に、必要な場合、またはユーザー定義の変換の変換演算子の結果の型から対象の型への標準変換を実行します。Finally, if required, performing a standard conversion from the result type of the user-defined or lifted conversion operator to the target type.

ユーザー定義変換しないの評価には、1 つ以上のユーザー定義またはリフトの変換演算子が含まれます。Evaluation of a user-defined conversion never involves more than one user-defined or lifted conversion operator. つまり、型から変換Sを入力するTからユーザー定義の変換は実行しない最初SXからユーザー定義の変換を実行し、XTします。In other words, a conversion from type S to type T will never first execute a user-defined conversion from S to X and then execute a user-defined conversion from X to T.

ユーザー定義の暗黙的または明示的な変換の評価の正確な定義は、次のセクションで提供されます。Exact definitions of evaluation of user-defined implicit or explicit conversions are given in the following sections. 定義の次の用語を使用します。The definitions make use of the following terms:

  • 場合、標準の暗黙的な変換 (標準の暗黙的な変換) 型からが存在するAB、どちらの場合とABinterface_types しAと呼ばれますに包含BBといいますencompass Aします。If a standard implicit conversion (Standard implicit conversions) exists from a type A to a type B, and if neither A nor B are interface_types, then A is said to be encompassed by B, and B is said to encompass A.
  • 最も外側の型一連の型では、セット内の他のすべての型を包含している 1 つの型。The most encompassing type in a set of types is the one type that encompasses all other types in the set. その他のすべての型を包含する 1 つの型の場合セットに最も外側の型がありません。If no single type encompasses all other types, then the set has no most encompassing type. 最も外側の型は、セットの「最大」の型をより直感的な用語で、先の他の種類ごとに暗黙的に変換できる 1 つの型。In more intuitive terms, the most encompassing type is the "largest" type in the set—the one type to which each of the other types can be implicitly converted.
  • 最も内側の型一連の型では、セット内の他のすべての種類に包含されている 1 つの型。The most encompassed type in a set of types is the one type that is encompassed by all other types in the set. 他のすべての型によって 1 つの型が含まれていない場合、セットが最も内側の型。If no single type is encompassed by all other types, then the set has no most encompassed type. 直感的な用語は、最も内側の型は、セット内の「最小」の型などの他の種類ごとに暗黙的に変換できる 1 つの型。In more intuitive terms, the most encompassed type is the "smallest" type in the set—the one type that can be implicitly converted to each of the other types.

暗黙的な変換のユーザー定義の処理Processing of user-defined implicit conversions

ユーザー定義型から暗黙的な変換Sを入力するTように処理されます。A user-defined implicit conversion from type S to type T is processed as follows:

  • 種類を特定するS0T0します。Determine the types S0 and T0. 場合SまたはTは null 許容型は、S0T0の基になる型をそれ以外の場合はS0T0と等しいSTそれぞれします。If S or T are nullable types, S0 and T0 are their underlying types, otherwise S0 and T0 are equal to S and T respectively.
  • 型のセットを見つけるD、どのユーザー定義の変換演算子を考慮します。Find the set of types, D, from which user-defined conversion operators will be considered. このセットから成るS0(場合S0がクラスまたは構造体) の基本クラスS0(場合S0クラスは、)、およびT0(場合T0がクラスまたは構造体)。This set consists of S0 (if S0 is a class or struct), the base classes of S0 (if S0 is a class), and T0 (if T0 is a class or struct).
  • 該当するユーザー定義およびリフト変換演算子のセットを見つけるUします。Find the set of applicable user-defined and lifted conversion operators, U. このセットは、クラスまたは構造体で宣言されているユーザー定義およびリフトの暗黙的な変換演算子で構成されますD包括的な型から変換するS型によって包含Tします。This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs in D that convert from a type encompassing S to a type encompassed by T. 場合Uは空の場合、変換が定義されていると、コンパイル時エラーが発生します。If U is empty, the conversion is undefined and a compile-time error occurs.
  • 特定のソースの種類を検索SX、演算子のU:Find the most specific source type, SX, of the operators in U:
    • いずれかの演算子のUから変換S、しSXSします。If any of the operators in U convert from S, then SX is S.
    • それ以外の場合、SXの演算子のソースの種類の結合されたセット内の最も内側の型は、Uします。Otherwise, SX is the most encompassed type in the combined set of source types of the operators in U. 型が見つからない最も内側の 1 つだけの場合に、変換があいまいなをコンパイル時エラーが発生します。If exactly one most encompassed type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • 最も固有のターゲット型を見つけるTX、演算子のU:Find the most specific target type, TX, of the operators in U:
    • いずれかの演算子の場合U変換T、しTXTIf any of the operators in U convert to T, then TX is T.
    • それ以外の場合、TXで一連の演算子のターゲット タイプの最も外側の型は、Uします。Otherwise, TX is the most encompassing type in the combined set of target types of the operators in U. 正確に 1 つの最も外側の型が見つからない場合、変換はあいまいですしとコンパイル時エラーが発生します。If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • 最も固有の変換演算子を検索します。Find the most specific conversion operator:
    • 場合Uから変換する 1 つだけのユーザー定義変換演算子が含まれていますSXTX、これは、最も固有の変換演算子。If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • の場合Uから変換する 1 つだけのリフト変換演算子が含まれていますSXTX、これは、最も固有の変換演算子。Otherwise, if U contains exactly one lifted conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • それ以外の場合、変換はあいまいですし、コンパイル時エラーが発生します。Otherwise, the conversion is ambiguous and a compile-time error occurs.
  • 最後に、変換が適用されます。Finally, apply the conversion:
    • 場合SないSXから、標準、暗黙的な変換し、SSXが実行されます。If S is not SX, then a standard implicit conversion from S to SX is performed.
    • 変換する最も固有の変換演算子が呼び出されるSXTXします。The most specific conversion operator is invoked to convert from SX to TX.
    • 場合TXないTから、標準、暗黙的な変換し、TXTが実行されます。If TX is not T, then a standard implicit conversion from TX to T is performed.

明示的な変換のユーザー定義の処理Processing of user-defined explicit conversions

型からユーザー定義の明示的な変換S入力Tように処理されます。A user-defined explicit conversion from type S to type T is processed as follows:

  • 種類を特定するS0T0します。Determine the types S0 and T0. 場合SまたはTは null 許容型は、S0T0の基になる型をそれ以外の場合はS0T0と等しいSTそれぞれします。If S or T are nullable types, S0 and T0 are their underlying types, otherwise S0 and T0 are equal to S and T respectively.
  • 型のセットを見つけるD、どのユーザー定義の変換演算子を考慮します。Find the set of types, D, from which user-defined conversion operators will be considered. このセットから成るS0(場合S0がクラスまたは構造体) の基本クラスS0(場合S0クラスは、)、 T0 (場合T0がクラスまたは構造体)、およびの基本クラスT0(場合T0クラスです)。This set consists of S0 (if S0 is a class or struct), the base classes of S0 (if S0 is a class), T0 (if T0 is a class or struct), and the base classes of T0 (if T0 is a class).
  • 該当するユーザー定義およびリフト変換演算子のセットを見つけるUします。Find the set of applicable user-defined and lifted conversion operators, U. このセットは、ユーザー定義およびリフト暗黙的または明示的な変換演算子は、クラスまたは構造体で宣言されているDを包括的な型から変換またはによって包含Sを包括的なまたはに包含型T.This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs in D that convert from a type encompassing or encompassed by S to a type encompassing or encompassed by T. 場合Uは空の場合、変換が定義されていると、コンパイル時エラーが発生します。If U is empty, the conversion is undefined and a compile-time error occurs.
  • 特定のソースの種類を検索SX、演算子のU:Find the most specific source type, SX, of the operators in U:
    • いずれかの演算子のUから変換S、しSXSします。If any of the operators in U convert from S, then SX is S.
    • それ以外の場合、いずれかの演算子のU包含する型から変換S、しSXこれらの演算子のソースの種類の結合されたセット内の最も内側にある型です。Otherwise, if any of the operators in U convert from types that encompass S, then SX is the most encompassed type in the combined set of source types of those operators. 型が見つからない、最も内側の場合に、変換があいまいなをコンパイル時エラーが発生します。If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs.
    • それ以外の場合、SXの演算子のソースの種類の結合されたセット内の最も外側の型は、Uします。Otherwise, SX is the most encompassing type in the combined set of source types of the operators in U. 正確に 1 つの最も外側の型が見つからない場合、変換はあいまいですしとコンパイル時エラーが発生します。If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • 最も固有のターゲット型を見つけるTX、演算子のU:Find the most specific target type, TX, of the operators in U:
    • いずれかの演算子の場合U変換T、しTXTIf any of the operators in U convert to T, then TX is T.
    • それ以外の場合、いずれかの演算子のUによって包含する型に変換T、しTXはこれらの演算子のターゲット型の結合されたセット内の最も外側の型。Otherwise, if any of the operators in U convert to types that are encompassed by T, then TX is the most encompassing type in the combined set of target types of those operators. 正確に 1 つの最も外側の型が見つからない場合、変換はあいまいですしとコンパイル時エラーが発生します。If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
    • それ以外の場合、TXで一連の演算子のターゲット タイプの最も内側の型は、Uします。Otherwise, TX is the most encompassed type in the combined set of target types of the operators in U. 型が見つからない、最も内側の場合に、変換があいまいなをコンパイル時エラーが発生します。If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs.
  • 最も固有の変換演算子を検索します。Find the most specific conversion operator:
    • 場合Uから変換する 1 つだけのユーザー定義変換演算子が含まれていますSXTX、これは、最も固有の変換演算子。If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • の場合Uから変換する 1 つだけのリフト変換演算子が含まれていますSXTX、これは、最も固有の変換演算子。Otherwise, if U contains exactly one lifted conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • それ以外の場合、変換はあいまいですし、コンパイル時エラーが発生します。Otherwise, the conversion is ambiguous and a compile-time error occurs.
  • 最後に、変換が適用されます。Finally, apply the conversion:
    • 場合SないSXから標準の明示的な変換、SSXが実行されます。If S is not SX, then a standard explicit conversion from S to SX is performed.
    • 変換する最も固有のユーザー定義変換演算子が呼び出されるSXTXします。The most specific user-defined conversion operator is invoked to convert from SX to TX.
    • 場合TXないTから標準の明示的な変換、TXTが実行されます。If TX is not T, then a standard explicit conversion from TX to T is performed.

匿名関数の変換Anonymous function conversions

Anonymous_method_expressionまたはlambda_expression匿名関数として分類されます (匿名関数式)。An anonymous_method_expression or lambda_expression is classified as an anonymous function (Anonymous function expressions). 式は、型がありませんが、互換性のあるデリゲート型または式ツリー型に暗黙的に変換できます。The expression does not have a type but can be implicitly converted to a compatible delegate type or expression tree type. 具体的には、匿名関数Fデリゲート型と互換性がD提供します。Specifically, an anonymous function F is compatible with a delegate type D provided:

  • 場合Fが含まれています、 anonymous_function_signature、しDF同じ数のパラメーターがあります。If F contains an anonymous_function_signature, then D and F have the same number of parameters.
  • 場合Fが含まれていない、 anonymous_function_signature、しDのパラメーターなしに限り、あらゆる種類の 0 個以上のパラメーターがあります。Dが、outパラメーター修飾子。If F does not contain an anonymous_function_signature, then D may have zero or more parameters of any type, as long as no parameter of D has the out parameter modifier.
  • 場合F、明示的に型指定されたパラメーターのリスト内の各パラメーターを持つDの対応するパラメーターとして、同じ型および修飾子を持つFします。If F has an explicitly typed parameter list, each parameter in D has the same type and modifiers as the corresponding parameter in F.
  • 場合F、暗黙的に型指定されたパラメーター リストを持つDにないrefまたはoutパラメーター。If F has an implicitly typed parameter list, D has no ref or out parameters.
  • 場合の本文Fが、式で、かつDが、void型を返すまたはFは async とD戻り値の型を持つTask、その後の各パラメーターFの型を指定、対応するパラメーターのDの本文F有効な式です (wrt) として許可されている場合、 statement_expression (式ステートメント)。If the body of F is an expression, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (wrt Expressions) that would be permitted as a statement_expression (Expression statements).
  • 場合の本文Fがステートメント ブロックで、かつDが、void型を返すまたはFは async とD戻り値の型を持つTask、その後の各パラメーターFの型を指定対応するパラメーターDの本文Fは有効なステートメント ブロックです (wrtブロック) いないreturnステートメント式を指定します。If the body of F is a statement block, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid statement block (wrt Blocks) in which no return statement specifies an expression.
  • 場合の本文F式であるとFは非同期ではないとD非 void の戻り値の型を持つTまたはFは async とD戻り値の型を持つTask<T>、その後の各パラメーターFの対応するパラメーターの型が指定Dの本文F有効な式です (wrt ) に暗黙的に変換可能Tします。If the body of F is an expression, and either F is non-async and D has a non-void return type T, or F is async and D has a return type Task<T>, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (wrt Expressions) that is implicitly convertible to T.
  • 場合の本文Fステートメント ブロックとFは非同期ではないとD非 void の戻り値の型を持つTまたはFは async とD戻り値の型を持つTask<T>、その後の各パラメーターFの対応するパラメーターの型が指定Dの本文Fは有効なステートメント ブロックです (wrtブロック) 各が到達可能な終了点でreturnステートメントは、暗黙的に変換できる式を指定します。Tします。If the body of F is a statement block, and either F is non-async and D has a non-void return type T, or F is async and D has a return type Task<T>, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid statement block (wrt Blocks) with a non-reachable end point in which each return statement specifies an expression that is implicitly convertible to T.

このセクションで、簡潔さを優先するためにタスクの種類の短い形式を使用してTaskTask<T>(非同期関数)。For the purpose of brevity, this section uses the short form for the task types Task and Task<T> (Async functions).

ラムダ式F式ツリー型と互換性がExpression<D>場合Fデリゲート型と互換性がDします。A lambda expression F is compatible with an expression tree type Expression<D> if F is compatible with the delegate type D. 匿名メソッド、ラムダ式のみをこの適用されないことに注意してください。Note that this does not apply to anonymous methods, only lambda expressions.

特定のラムダ式は、式ツリー型に変換できません。場合でも、変換が存在するコンパイル時に失敗します。Certain lambda expressions cannot be converted to expression tree types: Even though the conversion exists, it fails at compile-time. これは、場合は、ラムダ式。This is the case if the lambda expression:

  • ブロック本文Has a block body
  • 単純型または複合代入演算子が含まれていますContains simple or compound assignment operators
  • 動的にバインドされている式が含まれていますContains a dynamically bound expression
  • 非同期にはIs async

次の例は、汎用デリゲート型を使用して、Func<A,R>型の引数を受け取る関数を表すA型の値を返すR:The examples that follow use a generic delegate type Func<A,R> which represents a function that takes an argument of type A and returns a value of type R:

delegate R Func<A,R>(A arg);

割り当てIn the assignments

Func<int,int> f1 = x => x + 1;                 // Ok

Func<int,double> f2 = x => x + 1;              // Ok

Func<double,int> f3 = x => x + 1;              // Error

Func<int, Task<int>> f4 = async x => x + 1;    // Ok

各匿名関数のパラメーターと戻り値の型は、匿名関数が割り当てられている変数の型から決まります。the parameter and return types of each anonymous function are determined from the type of the variable to which the anonymous function is assigned.

最初の割り当てが正常に匿名関数をデリゲート型に変換Func<int,int>ため、x型が指定intx+1型に暗黙的に変換できる有効な式ですintします。The first assignment successfully converts the anonymous function to the delegate type Func<int,int> because, when x is given type int, x+1 is a valid expression that is implicitly convertible to type int.

同様に、2 つ目の割り当てを正常に変換関数を匿名デリゲートの型にFunc<int,double>ため、結果のx+1(型のint) 型に暗黙的に変換できるdoubleします。Likewise, the second assignment successfully converts the anonymous function to the delegate type Func<int,double> because the result of x+1 (of type int) is implicitly convertible to type double.

しかし、3 番目の割り当てが、コンパイル時エラー、x型が指定doubleの結果x+1(型のdouble) 型に暗黙的に変換可能でないintします。However, the third assignment is a compile-time error because, when x is given type double, the result of x+1 (of type double) is not implicitly convertible to type int.

4 番目の割り当てが正常に匿名の非同期関数をデリゲート型に変換Func<int, Task<int>>ため、結果のx+1(型のint) 結果の型に暗黙的に変換できるintタスクの種類のTask<int>.The fourth assignment successfully converts the anonymous async function to the delegate type Func<int, Task<int>> because the result of x+1 (of type int) is implicitly convertible to the result type int of the task type Task<int>.

匿名関数はオーバー ロードの解決に影響を与える可能性があり、型の推定に参加します。Anonymous functions may influence overload resolution, and participate in type inference. 参照してください関数メンバーの詳細。See Function members for further details.

デリゲート型への匿名関数の変換の評価Evaluation of anonymous function conversions to delegate types

匿名関数のデリゲート型への変換では、匿名関数とキャプチャされた外部変数の評価時にアクティブになっている一連の (場合によっては空) を参照するデリゲート インスタンスを生成します。Conversion of an anonymous function to a delegate type produces a delegate instance which references the anonymous function and the (possibly empty) set of captured outer variables that are active at the time of the evaluation. デリゲートが呼び出されたときに、匿名関数の本体が実行されます。When the delegate is invoked, the body of the anonymous function is executed. デリゲートによって参照される外部変数をキャプチャのセットを使用して、本体内のコードが実行されます。The code in the body is executed using the set of captured outer variables referenced by the delegate.

匿名関数によって生成されたデリゲートの呼び出しリストには、1 つのエントリが含まれています。The invocation list of a delegate produced from an anonymous function contains a single entry. 正確なターゲット オブジェクトと、デリゲートのターゲット メソッドが指定されていません。The exact target object and target method of the delegate are unspecified. 具体的には、指定されていないかどうか、デリゲートのターゲット オブジェクトは、 nullthis外側の関数メンバー、またはその他のオブジェクトの値。In particular, it is unspecified whether the target object of the delegate is null, the this value of the enclosing function member, or some other object.

同じデリゲート型への外部変数のキャプチャされたインスタンスの同じ (場合によっては空) のセットの意味的に同一の匿名関数の変換は許可されている (ただし必要ありません) を同じデリゲート インスタンスを返します。Conversions of semantically identical anonymous functions with the same (possibly empty) set of captured outer variable instances to the same delegate types are permitted (but not required) to return the same delegate instance. 匿名関数の実行、すべてのケースで、表示されるのと同じ引数を指定したのと同じ効果を意味する意味的に同一の用語がここで使用されます。The term semantically identical is used here to mean that execution of the anonymous functions will, in all cases, produce the same effects given the same arguments. このルールは、最適化するのには、次のようなコードを許可します。This rule permits code such as the following to be optimized.

delegate double Function(double x);

class Test
{
    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void F(double[] a, double[] b) {
        a = Apply(a, (double x) => Math.Sin(x));
        b = Apply(b, (double y) => Math.Sin(y));
        ...
    }
}

2 つの関数を匿名デリゲートを同じ (空) と匿名関数は意味が同じであるため、キャプチャされた外部変数の設定があるため、コンパイラがデリゲートに同じターゲット メソッドを参照してください。 許可されています。Since the two anonymous function delegates have the same (empty) set of captured outer variables, and since the anonymous functions are semantically identical, the compiler is permitted to have the delegates refer to the same target method. 実際には、コンパイラは、両方の匿名関数式から、まったく同じデリゲート インスタンスを返すに許可されます。Indeed, the compiler is permitted to return the very same delegate instance from both anonymous function expressions.

式ツリー型への匿名関数の変換の評価Evaluation of anonymous function conversions to expression tree types

匿名関数の式ツリー型への変換、式ツリーを生成します (式ツリー型)。Conversion of an anonymous function to an expression tree type produces an expression tree (Expression tree types). 正確には、匿名関数の変換の評価は、匿名関数自体の構造を表すオブジェクトの構造の構築につながります。More precisely, evaluation of the anonymous function conversion leads to the construction of an object structure that represents the structure of the anonymous function itself. それを作成するための正確なプロセスと同様に、式ツリーの厳密な構造は、実装定義です。The precise structure of the expression tree, as well as the exact process for creating it, are implementation defined.

実装例Implementation example

このセクションでは、その他の c# コンストラクトの観点から匿名関数の変換の実装について説明します。This section describes a possible implementation of anonymous function conversions in terms of other C# constructs. ここで説明されている実装 Microsoft c# コンパイラで使用される同じ原則に基づいていますが、1 つだけのことも、必須の実装ではではありません。The implementation described here is based on the same principles used by the Microsoft C# compiler, but it is by no means a mandated implementation, nor is it the only one possible. ごく簡単に、この仕様の範囲外の正確なセマンティクスは、式ツリーへの変換を紹介します。It only briefly mentions conversions to expression trees, as their exact semantics are outside the scope of this specification.

このセクションの残りの部分では、異なる特性を持つ匿名関数を含むコードのいくつかの例を示します。The remainder of this section gives several examples of code that contains anonymous functions with different characteristics. それぞれの例については、のみ c# の他のコンストラクトを使用するコードに対応する翻訳が提供されます。For each example, a corresponding translation to code that uses only other C# constructs is provided. 識別子の例についてでD次のデリゲート型で表すと見なされます。In the examples, the identifier D is assumed by represent the following delegate type:

public delegate void D();

匿名関数の最も単純な形式は、外部変数をキャプチャしません。The simplest form of an anonymous function is one that captures no outer variables:

class Test
{
    static void F() {
        D d = () => { Console.WriteLine("test"); };
    }
}

これは、匿名関数のコードが置かれているコンパイラによって生成された静的メソッドを参照するデリゲートのインスタンス化に書き換えることができます。This can be translated to a delegate instantiation that references a compiler generated static method in which the code of the anonymous function is placed:

class Test
{
    static void F() {
        D d = new D(__Method1);
    }

    static void __Method1() {
        Console.WriteLine("test");
    }
}

匿名関数がのインスタンス メンバーを参照する次の例では、 this:In the following example, the anonymous function references instance members of this:

class Test
{
    int x;

    void F() {
        D d = () => { Console.WriteLine(x); };
    }
}

これは、匿名関数のコードを含むコンパイラによって生成されたインスタンス メソッドに書き換えることができます。This can be translated to a compiler generated instance method containing the code of the anonymous function:

class Test
{
    int x;

    void F() {
        D d = new D(__Method1);
    }

    void __Method1() {
        Console.WriteLine(x);
    }
}

この例では、匿名関数は、ローカル変数をキャプチャします。In this example, the anonymous function captures a local variable:

class Test
{
    void F() {
        int y = 123;
        D d = () => { Console.WriteLine(y); };
    }
}

ローカル変数の有効期間を少なくとも、関数を匿名デリゲートの有効期間まで延長する必要があります。The lifetime of the local variable must now be extended to at least the lifetime of the anonymous function delegate. これは、コンパイラによって生成されたクラスのフィールドに、ローカル変数を「ホイスト」で実現できます。This can be achieved by "hoisting" the local variable into a field of a compiler generated class. ローカル変数のインスタンス化 (ローカル変数のインスタンス化)、コンパイラによって生成されたクラスのインスタンス内のフィールドへのアクセスに対応するローカル変数にアクセスするのインスタンスを作成するのには対応し、コンパイラによって生成されたクラスです。Instantiation of the local variable (Instantiation of local variables) then corresponds to creating an instance of the compiler generated class, and accessing the local variable corresponds to accessing a field in the instance of the compiler generated class. さらに、匿名関数には、コンパイラによって生成されたクラスのインスタンス メソッドがようになります。Furthermore, the anonymous function becomes an instance method of the compiler generated class:

class Test
{
    void F() {
        __Locals1 __locals1 = new __Locals1();
        __locals1.y = 123;
        D d = new D(__locals1.__Method1);
    }

    class __Locals1
    {
        public int y;

        public void __Method1() {
            Console.WriteLine(y);
        }
    }
}

最後に、キャプチャの関数は次の匿名thisと有効期間の異なる 2 つのローカル変数。Finally, the following anonymous function captures this as well as two local variables with different lifetimes:

class Test
{
    int x;

    void F() {
        int y = 123;
        for (int i = 0; i < 10; i++) {
            int z = i * 2;
            D d = () => { Console.WriteLine(x + y + z); };
        }
    }
}

ここでは、コンパイラによって生成されたクラスを作成する for each ステートメントで、さまざまな要素でローカル変数は、独立した有効期間を持つことができますをどのローカル変数がキャプチャをブロックします。Here, a compiler generated class is created for each statement block in which locals are captured such that the locals in the different blocks can have independent lifetimes. インスタンス__Locals2、inner ステートメント ブロックのコンパイラによって生成されたクラスには、ローカル変数が含まれています。zのインスタンスを参照するフィールドと__Locals1します。An instance of __Locals2, the compiler generated class for the inner statement block, contains the local variable z and a field that references an instance of __Locals1. インスタンス__Locals1、外側のステートメント ブロックのコンパイラによって生成されたクラスには、ローカル変数が含まれています。yを参照するフィールドとthis外側の関数メンバーの。An instance of __Locals1, the compiler generated class for the outer statement block, contains the local variable y and a field that references this of the enclosing function member. アクセスには、これらのデータ構造ですべてのキャプチャされた外部変数のインスタンスを通じて__Local2、および匿名関数のコードはそのクラスのインスタンス メソッドとして実装できます。With these data structures it is possible to reach all captured outer variables through an instance of __Local2, and the code of the anonymous function can thus be implemented as an instance method of that class.

class Test
{
    void F() {
        __Locals1 __locals1 = new __Locals1();
        __locals1.__this = this;
        __locals1.y = 123;
        for (int i = 0; i < 10; i++) {
            __Locals2 __locals2 = new __Locals2();
            __locals2.__locals1 = __locals1;
            __locals2.z = i * 2;
            D d = new D(__locals2.__Method1);
        }
    }

    class __Locals1
    {
        public Test __this;
        public int y;
    }

    class __Locals2
    {
        public __Locals1 __locals1;
        public int z;

        public void __Method1() {
            Console.WriteLine(__locals1.__this.x + __locals1.y + z);
        }
    }
}

ここで適用されるローカル変数をキャプチャする同じ手法は、匿名関数を式ツリーに変換する場合にも使用できます。コンパイラによって生成されたオブジェクトへの参照は、式ツリーに格納できるし、これらのオブジェクトのフィールドにアクセスすると、ローカル変数へのアクセスを表すことができます。The same technique applied here to capture local variables can also be used when converting anonymous functions to expression trees: References to the compiler generated objects can be stored in the expression tree, and access to the local variables can be represented as field accesses on these objects. このアプローチの利点は、デリゲート、式ツリーの間で共有する「リフト」ローカル変数でできることです。The advantage of this approach is that it allows the "lifted" local variables to be shared between delegates and expression trees.

メソッド グループ変換Method group conversions

暗黙的な変換 (暗黙的な変換)、メソッド グループからが存在する (式の分類) 互換性のあるデリゲート型にします。An implicit conversion (Implicit conversions) exists from a method group (Expression classifications) to a compatible delegate type. デリゲート型を指定してDと式Eメソッド グループに分類されるからの暗黙的な変換が存在するED場合Eはその通常の形式 (該当する少なくとも 1 つのメソッドが含まれています適用可能な関数メンバー)、引数リストへの修飾子をパラメーターの型の使用して構築されたD以下で説明するようにします。Given a delegate type D and an expression E that is classified as a method group, an implicit conversion exists from E to D if E contains at least one method that is applicable in its normal form (Applicable function member) to an argument list constructed by use of the parameter types and modifiers of D, as described in the following.

メソッド グループからの変換のコンパイル時のアプリケーションEをデリゲート型にDについては、次で説明します。The compile-time application of a conversion from a method group E to a delegate type D is described in the following. なおからの暗黙的な変換が存在するED変換のコンパイル時のアプリケーションがエラーなしに成功するには保証されません。Note that the existence of an implicit conversion from E to D does not guarantee that the compile-time application of the conversion will succeed without error.

  • 1 つのメソッドMが選択されているメソッドの呼び出しに対応する (メソッドの呼び出し) フォームのE(A)、次の変更。A single method M is selected corresponding to a method invocation (Method invocations) of the form E(A), with the following modifications:
    • 引数リストA式、変数として、型および修飾子を使用して、各分類済みの一覧を示します (refまたはout) に対応するパラメーターのformal_parameter_listD.The argument list A is a list of expressions, each classified as a variable and with the type and modifier (ref or out) of the corresponding parameter in the formal_parameter_list of D.
    • 候補となるメソッドと見なされますが、標準形式で適用されるメソッドのみ (適用可能な関数メンバー)、拡張形式でのみ適用されません。The candidate methods considered are only those methods that are applicable in their normal form (Applicable function member), not those applicable only in their expanded form.
  • 場合、アルゴリズムのメソッドの呼び出しコンパイル時エラーが発生し、エラーが発生します。If the algorithm of Method invocations produces an error, then a compile-time error occurs. それ以外の場合、アルゴリズムが最適な 1 つのメソッドが生成されますM同じ同数のパラメーターを持つDと変換が存在すると見なされます。Otherwise the algorithm produces a single best method M having the same number of parameters as D and the conversion is considered to exist.
  • 選択したメソッドM互換である必要があります (デリゲートの互換性) デリゲート型とD、またはそれ以外の場合、コンパイル時エラーが発生しました。The selected method M must be compatible (Delegate compatibility) with the delegate type D, or otherwise, a compile-time error occurs.
  • 場合、選択したメソッドM、インスタンス メソッドに関連付けられたインスタンス式であるEデリゲートのターゲット オブジェクトを決定します。If the selected method M is an instance method, the instance expression associated with E determines the target object of the delegate.
  • インスタンス式でメンバー アクセスによって表される拡張メソッドを選択したメソッド M には、そのインスタンス式は、デリゲートの対象オブジェクトを決定します。If the selected method M is an extension method which is denoted by means of a member access on an instance expression, that instance expression determines the target object of the delegate.
  • 変換の結果は、型の値 D、新しく作成されたデリゲート メソッドとターゲットの選択したオブジェクトを指す namely します。The result of the conversion is a value of type D, namely a newly created delegate that refers to the selected method and target object.
  • このプロセスが拡張メソッド、デリゲートの作成を簡単になることができる場合のアルゴリズムメソッドの呼び出しインスタンス メソッドの検索に失敗したが、処理の呼び出しに成功すると、E(A)拡張機能としてメソッドの呼び出し (拡張メソッド呼び出し)。Note that this process can lead to the creation of a delegate to an extension method, if the algorithm of Method invocations fails to find an instance method but succeeds in processing the invocation of E(A) as an extension method invocation (Extension method invocations). こうして作成したデリゲートでは、拡張メソッドと、最初の引数をキャプチャします。A delegate thus created captures the extension method as well as its first argument.

次の例では、メソッド グループ変換を示しています。The following example demonstrates method group conversions:

delegate string D1(object o);

delegate object D2(string s);

delegate object D3();

delegate string D4(object o, params object[] a);

delegate string D5(int i);

class Test
{
    static string F(object o) {...}

    static void G() {
        D1 d1 = F;            // Ok
        D2 d2 = F;            // Ok
        D3 d3 = F;            // Error -- not applicable
        D4 d4 = F;            // Error -- not applicable in normal form
        D5 d5 = F;            // Error -- applicable but not compatible

    }
}

代入d1メソッド グループを暗黙的に変換しますF型の値にD1します。The assignment to d1 implicitly converts the method group F to a value of type D1.

代入d2を弱い派生 (反変) パラメーターの型を持つメソッドにデリゲートを作成することはしより (共変性) の戻り値の型を派生する方法を示します。The assignment to d2 shows how it is possible to create a delegate to a method that has less derived (contravariant) parameter types and a more derived (covariant) return type.

代入d3表示変換が存在しないかどうか、メソッドは使用できません。The assignment to d3 shows how no conversion exists if the method is not applicable.

代入d4メソッドが、標準形式で適用する必要がありますの方法を示します。The assignment to d4 shows how the method must be applicable in its normal form.

代入d5参照型に対してのみ異なるデリゲートとメソッドのパラメーターと戻り値の型を許可する方法を示しています。The assignment to d5 shows how parameter and return types of the delegate and method are allowed to differ only for reference types.

すべて、他の明示的および暗黙的な変換と明示的にメソッド グループ変換を実行するキャスト演算子を使用できます。As with all other implicit and explicit conversions, the cast operator can be used to explicitly perform a method group conversion. 例では、そのため、Thus, the example

object obj = new EventHandler(myDialog.OkClick);

代わりに書き込まれる可能性があります。could instead be written

object obj = (EventHandler)myDialog.OkClick;

メソッド グループは、オーバー ロードの解決に影響を与えるし、型の推定に参加可能性があります。Method groups may influence overload resolution, and participate in type inference. 参照してください関数メンバーの詳細。See Function members for further details.

メソッド グループ変換の実行時の評価は、次のように処理されます。The run-time evaluation of a method group conversion proceeds as follows:

  • 関連付けられたインスタンス式からデリゲートのターゲット オブジェクトを確認するコンパイル時に選択されているメソッドがインスタンス メソッド、またはインスタンス メソッドとしてアクセスされる拡張メソッドは、 E:If the method selected at compile-time is an instance method, or it is an extension method which is accessed as an instance method, the target object of the delegate is determined from the instance expression associated with E:
    • インスタンス式が評価されます。The instance expression is evaluated. この評価は、例外を発生させ、その後の手順は実行されません。If this evaluation causes an exception, no further steps are executed.
    • インスタンス式がある場合、 reference_type、ターゲット オブジェクトをインスタンス式で計算された値になります。If the instance expression is of a reference_type, the value computed by the instance expression becomes the target object. 選択したメソッドがインスタンス メソッドと、ターゲット オブジェクトがかどうかnullSystem.NullReferenceExceptionがスローされます、以降の手順は実行されません。If the selected method is an instance method and the target object is null, a System.NullReferenceException is thrown and no further steps are executed.
    • インスタンス式がある場合、 value_type、ボックス化操作 (ボックス化変換) は、オブジェクトに値を変換する実行し、このオブジェクトがターゲット オブジェクトになります。If the instance expression is of a value_type, a boxing operation (Boxing conversions) is performed to convert the value to an object, and this object becomes the target object.
  • それ以外の場合、選択したメソッドは静的メソッドの呼び出しの一部ですが、デリゲートのターゲット オブジェクトとnullします。Otherwise the selected method is part of a static method call, and the target object of the delegate is null.
  • デリゲート型の新しいインスタンス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.
  • 新しいデリゲート インスタンスがコンパイル時に決定されたメソッドへの参照で初期化され、上、ターゲット オブジェクトへの参照が計算されます。The new delegate instance is initialized with a reference to the method that was determined at compile-time and a reference to the target object computed above.