コンバージョンConversions

*変換 _ を使用すると、式を特定の型として扱うことができます。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. 変換は *暗黙的* または _ explicit * にすることができます。これにより、明示的なキャストが必要かどうかが決まります。Conversions can be implicit or _*explicit**, and this determines whether an explicit cast is required. たとえば、型から int 型への変換 long は暗黙的なので、型の式は int 暗黙的に型として扱うことができ long ます。For 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:

  • Id 変換Identity conversions
  • 暗黙の数値変換Implicit numeric conversions
  • 暗黙的な列挙変換Implicit enumeration conversions
  • 暗黙的な挿入文字列の変換Implicit interpolated string 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.

  • objectとは同等と見なされるため、 dynamic との間の id 変換 object と、 dynamic のすべての出現箇所をで置き換える場合の構築された型の間の id 変換があり dynamic object ます。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:

  • から、、、、、 sbyte short int long float double または decimalFrom sbyte to short, int, long, float, double, or decimal.
  • から、、、、、、、、、の byte short ushort int uint long ulong float double いずれかに decimal なります。From byte to short, ushort, int, uint, long, ulong, float, double, or decimal.
  • から、、、、 short int long float double または decimalFrom short to int, long, float, double, or decimal.
  • から、、、、、、の ushort int uint long ulong float double いずれかに decimal なります。From ushort to int, uint, long, ulong, float, double, or decimal.
  • から int 、、、 long float double または decimalFrom int to long, float, double, or decimal.
  • から、、、、 uint long ulong float double または decimalFrom uint to long, ulong, float, double, or decimal.
  • から long float 、、 double または decimalFrom long to float, double, or decimal.
  • から ulong float 、、 double または decimalFrom ulong to float, double, or decimal.
  • から、、、、、、、 char ushort 、の int uint long ulong float double いずれかに decimal なります。From char to ushort, int, uint, long, ulong, float, double, or decimal.
  • float から doubleFrom float to double.

、、 int 、またはからへの変換 uint long ulong float またはからへの変換では、 long 精度が ulong double 失われる可能性がありますが、マグニチュードの損失は発生しません。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 。そのため、他の整数型の値が型に自動的に変換されることはありません charThere 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 に変換し、基になる型が enum_type である任意の nullable_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. Null 非許容の値型から null 非許容の値型に変換する定義済みの暗黙的な id および数値変換については、 S 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?.
  • からへの暗黙の型変換 S T?An implicit conversion from S to T?.

からへの基になる変換に基づく暗黙の null 許容型変換の評価は、次のように行われ S T ます。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 S T ラップ (null 許容型) が行われ T T? ます。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 許容型変換がからへの変換である場合 S T? 、変換はからへの基になる変換として評価された後、からへのラップが行われ S T T T? ます。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_type から object およびへの dynamicFrom 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_typeT 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 SE 要素型の array_typeT TE は、次のすべての条件が満たされています。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:
    • ST の要素型のみが異なります。S and T differ only in element type. つまり、との S T 次元数は同じです。In other words, S and T have the same number of dimensions.
    • SEとはどちらも TE reference_type s です。Both SE and TE are reference_type s.
    • からへの暗黙の参照変換が存在し SE TE ます。An implicit reference conversion exists from SE to TE.
  • 任意の array_type から、 System.Array およびそれが実装するインターフェイス。From any array_type to System.Array and the interfaces it implements.
  • S[] System.Collections.Generic.IList<T> からへの暗黙的な id または参照の変換がある場合は、1次元配列型からとその基本 S インターフェイス TFrom 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_type から、 System.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_type から T reference_type への暗黙的な id または参照への変換があり、 T0 への id 変換がある場合は、reference_type にし T0 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.
  • インターフェイスまたはデリゲート型への暗黙的な id または参照の変換がある場合は、任意の reference_type からインターフェイスまたはデリゲート型に T 変換 T0 され、分散変換可能 T0 (変位変換) がに 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_type s 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. object dynamic System.ValueType Non_nullable_value_type によって実装されている任意の 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.

基になる non_nullable_value_type から参照型へのボックス変換が存在する場合にのみ、 nullable_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 があり I0 、への id 変換がある場合に、インターフェイス型へのボックス変換があり I0 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

との割り当ては、 s2 i 暗黙的な動的変換を使用します。この場合、操作のバインドは実行時まで中断されます。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 ませんでした intA conversion is found to string but not to int.

暗黙の定数式の変換Implicit constant expression conversions

暗黙の定数式の変換では、次の変換が許可されます。An implicit constant expression conversion permits the following conversions:

  • 型の constant_expression (定数式) は int sbytebyte short ushort uint 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.
  • Constant_expression の値が負でない場合は、型の constant_expressionlong 型に変換でき ulong ます。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 よって実装されている任意のインターフェイスへ CFrom T to its effective base class C, from T to any base class of C, and from T to any interface implemented by C. 実行時に、 T が値型の場合、変換はボックス化変換として実行されます。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. 実行時に、 T が値型の場合、変換はボックス化変換として実行されます。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). 実行時に、 U が値型の場合、 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 参照型への暗黙的な変換があり S0 、への id 変換がある場合は、を参照型に変換し S0 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 インターフェイス型またはデリゲート型への暗黙的な変換が存在 I0 し、 I0 が変位 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). 実行時に、 T が値型の場合、変換はボックス化変換として実行されます。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_type から別の numeric_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:

  • から、、、、 sbyte byte ushort uint ulong または charFrom sbyte to byte, ushort, uint, ulong, or char.
  • から byte およびへの sbyte charFrom byte to sbyte and char.
  • から、、、、、 short sbyte byte ushort uint ulong または charFrom short to sbyte, byte, ushort, uint, ulong, or char.
  • から ushort 、、、 sbyte byte short または charFrom ushort to sbyte, byte, short, or char.
  • から、、、、、、の int sbyte byte short ushort uint ulong いずれかに char なります。From int to sbyte, byte, short, ushort, uint, ulong, or char.
  • から、、、、、 uint sbyte byte short ushort int または charFrom uint to sbyte, byte, short, ushort, int, or char.
  • から、、、、、、、 long sbyte 、の byte short ushort int uint ulong いずれかに char なります。From long to sbyte, byte, short, ushort, int, uint, ulong, or char.
  • から、、、、、、、 ulong sbyte 、の byte short ushort int uint long いずれかに char なります。From ulong to sbyte, byte, short, ushort, int, uint, long, or char.
  • から char sbyte 、、 byte または shortFrom char to sbyte, byte, or short.
  • から、、、、、、、、、、の float sbyte byte short ushort int uint long ulong char いずれかに decimal なります。From float to sbyte, byte, short, ushort, int, uint, long, ulong, char, or decimal.
  • から、、、、、、、、、 double sbyte byte 、の short ushort int uint long ulong char float いずれかに decimal なります。From double to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or decimal.
  • から、、、、、、、、、 decimal sbyte byte 、の short ushort int uint long ulong char float いずれかに double なります。From decimal to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double.

明示的な変換には暗黙的な数値変換と明示的な数値変換がすべて含まれているため、キャスト式 (cast 式) を使用して任意の numeric_type から他の任意の numeric_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.
  • からへの変換 doublefloat は、 double 値は最も近い値に丸められ 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. 値が NaN の場合は、 double 結果も nan になります。If the double value is NaN, the result is also NaN.
  • floatまたはからへの変換では、変換元の double decimal 値が表現に変換され、 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 結果は0になります。If the source value is too small to represent as a decimal, the result becomes zero. ソース値が NaN、無限大、または大きすぎてとして表現できない場合は、 decimal System.OverflowException がスローされます。If the source value is NaN, infinity, or too large to represent as a decimal, a System.OverflowException is thrown.
  • からまたはへの変換では、 decimal float 値は double decimal 最も近い値 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:

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

2つの型の間の明示的な列挙型変換は、参加している enum_typeenum_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 E byte 変換 (明示的な数値変換) として処理され、からへの変換は、からへの暗黙的な数値変換 int byte byte E (暗黙的な数値変換) と byte int して処理されます。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 非許容の値型から S null 非許容の値型 T (id 変換暗黙的な数値変換暗黙の列挙変換明示的な数値変換、明示 的な列挙変換) に変換される定義済みの明示的な変換のそれぞれに対して、次の 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?.
  • からへの明示的な変換 S T?An explicit conversion from S to T?.
  • からへの明示的な変換 S? TAn explicit conversion from S? to T.

からの基になる変換に基づく null 許容型変換の評価は、次のよう S に実行され T ます。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 S T 、からへのラップが行われ T T? ます。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 許容型変換がからへの変換である場合 S T? 、変換はからへの基になる変換として評価された後、からへのラップが行われ S T T T? ます。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 その後にからへの基になる変換が行われ S T ます。If 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:

  • object dynamic 他の reference_type との間。From object and dynamic to any other reference_type.
  • 任意の class_type から S 任意の class_typeT 、指定された S はの基本クラスです TFrom any class_type S to any class_type T, provided S is a base class of T.
  • 任意の class_type から S 任意の interface_type に対して、指定された T S は sealed ではなく、指定されたはを S 実装しません TFrom 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 SFrom 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 はから派生していません TFrom any interface_type S to any interface_type T, provided S is not derived from T.
  • 要素型を持つ array_type から S SE 要素型の array_typeT TE は、次のすべての条件が満たされています。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:
    • ST の要素型のみが異なります。S and T differ only in element type. つまり、との S T 次元数は同じです。In other words, S and T have the same number of dimensions.
    • SEとはどちらも TE reference_type s です。Both SE and TE are reference_type s.
    • からへの明示的な参照変換が存在し SE TE ます。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.
  • S[] System.Collections.Generic.IList<T> からへの明示的な参照変換がある場合は、1次元配列型からとその基本インターフェイス S TFrom 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> T[] への明示的な id または参照変換がある場合、とその基本インターフェイスは、1次元配列型に S T なります。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 id 変換がある場合は、参照型から参照型へ TFrom 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 明示的な参照変換があり、がに変換可能であるか、 T0 T0 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> 次の保留の各型パラメーターに対しても互換性がありません Xi DFrom 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 または参照変換が存在し Si Ti ます。If Xi is covariant, then there is an implicit or explicit identity or reference conversion from Si to Ti.
    • Xiが反変の場合、 Si とは両方とも Ti 同じか、または両方の参照型です。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. ボックス化解除変換は、型 objectdynamic 任意の System.ValueType non_nullable_value_type、任意の interface_type から、 interface_type を実装する任意の non_nullable_value_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_type にアンボックス変換が存在する場合、参照型から nullable_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 インターフェイス型からのアンボックス変換があり I0 、への id 変換がある場合、値型はインターフェイス型からのボックス化変換を持ち I0 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 インターフェイス型またはデリゲート型からのアンボックス変換がある場合、値型はインターフェイス型からのアンボックス変換を持ちます。また、は、に変換可能であるか、またはに変換可能 I0 I0 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. Nullable_type への null 参照のボックス化を解除すると、 nullable_type の null 値が生成されます。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

へのの最適な変換 o C は、明示的な参照変換としてコンパイル時に検出されます。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. へのの d 変換 C は、明示的な動的変換として、実行時に中断されます。実行時には、実行時の型からへのユーザー定義変換が 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:

  • の有効な基本クラスからの C T 任意の T 基底クラスへの C TFrom the effective base class C of T to T and from any base class of C to T. 実行時に、 T が値型の場合、変換はボックス化解除変換として実行されます。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. 実行時に、 T が値型の場合、変換はボックス化解除変換として実行されます。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 への暗黙的な変換はまだありません T IFrom T to any interface_type I provided there is not already an implicit conversion from T to I. 実行時に、 T が値型の場合、変換はボックス化変換として実行され、その後に明示的な参照変換が行われます。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.
  • 型パラメーターから U への T 、指定されたは T U (型パラメーター制約) に依存します。From a type parameter U to T, provided T depends on U (Type parameter constraints). 実行時に、 U が値型の場合、 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 
    }
}

への直接的な明示的な変換が許可されている場合は、がを t int 返すことが簡単であると考えられ X<int>.F(7)  7L ます。If 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 に直接変換することはできません longThis 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 A ます。In 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 またはが null 許容型である場合、はその T S0 T0 基になる型を表します。それ以外の場合、と S0 T0S それぞれとに等しく T なります。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:

  • S0T0 の型は異なります。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.
  • S0 T0 はどちらも interface_type ではありません。Neither S0 nor T0 is an interface_type.
  • ユーザー定義の変換を除外する場合、からへの S 変換 T またはから T への変換は存在しません SExcluding 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 非許容の値型から null 非許容の値型に変換するユーザー定義の変換演算子が指定されている S 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 ユーザー定義変換、およびからへのラップを行い S T T T? ます。ただし、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.

ユーザー定義の変換の評価では、複数のユーザー定義変換演算子またはリフト変換演算子は必要ありません。Evaluation of a user-defined conversion never involves more than one user-defined or lifted conversion operator. 言い換えると、型から S 型への変換で T は、最初にからへのユーザー定義変換が実行されてから、 S X からへのユーザー定義変換が実行されることはありません X TIn 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:

  • 標準の暗黙的な変換 (標準の暗黙的な変換) が型から型に存在する場合、 A とがどちらも B interface_type ない場合 A BA は *包含で あると見なされ、_ を B 囲むと言い B ** * 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_type s, 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.
  • 型のセットの中で 最も内側 にある型は、セット内の他のすべての型に包含されている型です。The most encompassed type in a set of types is the one type that is encompassed by all other types in the set. 他のすべての型に包含されている型がない場合は、そのセットに最も包含されていない型はありません。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:

  • S0 とを確認し T0 ます。Determine the types S0 and T0. Sまたは T が null 許容型であり、 S0 かつが基になる型である場合は。それ以外の場合、 T0 S0T0S それぞれとに T なります。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 SSX はに S なります。If any of the operators in U convert from S, then SX is S.
    • それ以外の場合、 SX は、の演算子のソースの種類の組み合わせにおいて最も包含される型です UOtherwise, 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 される場合、はに TX T なります。If any of the operators in U convert to T, then TX is T.
    • それ以外の場合、 TX は、内の演算子のターゲット型の集合に含まれる最も外側の型です UOtherwise, 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つだけ含まれている場合 SX TX は、これが最も具体的な変換演算子です。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つだけ含まれている場合 SX は、 TX これが最も具体的な変換演算子になります。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 、からへの標準の暗黙的な変換 S SX が実行されます。If S is not SX, then a standard implicit conversion from S to SX is performed.
    • からに変換するために、最も具体的な変換演算子が呼び出され SX TX ます。The most specific conversion operator is invoked to convert from SX to TX.
    • TXがでない場合は T 、からへの標準の暗黙的な変換 TX T が実行されます。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:

  • S0 とを確認し T0 ます。Determine the types S0 and T0. Sまたは T が null 許容型であり、 S0 かつが基になる型である場合は。それ以外の場合、 T0 S0T0S それぞれとに T なります。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 SSX はに S なります。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 は、内の演算子のソース型の組み合わせに含まれる最も外側の型です UOtherwise, 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 される場合、はに TX T なります。If 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 は、内の演算子のターゲット型の組み合わせに含まれる最も内側の型です UOtherwise, 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つだけ含まれている場合 SX TX は、これが最も具体的な変換演算子です。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つだけ含まれている場合 SX は、 TX これが最も具体的な変換演算子になります。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 、からへの標準の明示的な変換 S SX が実行されます。If S is not SX, then a standard explicit conversion from S to SX is performed.
    • からに変換するために、ユーザー定義の最も限定的な変換演算子が呼び出され SX TX ます。The most specific user-defined conversion operator is invoked to convert from SX to TX.
    • TXがでない場合は T 、からへの標準の明示的な変換 TX T が実行されます。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.
  • に anonymous_function_signature が含まれていない場合、には、パラメーター F 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 はまたはパラメーターがありません outIf F has an implicitly typed parameter list, D has no ref or out parameters.
  • の本体が式で、戻り値の型がであるか、または非同期で、戻り値の型がある場合、の各パラメーターには、の F D 対応する void F D Task F パラメーターの型が指定され D ます。の本文 F は、 statement_expression (式ステートメント) として許可される有効な式 (wrt ) です。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).
  • の本体がステートメントブロックで、戻り値の型が、または async で戻り値の型がである場合、の各パラメーターには、の対応するパラメーターの型が指定されています。この場合、の F D void F D Task F D 本文 F は有効なステートメントブロック (wrt block) で、ステートメントで式が指定されていません returnIf 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.
  • の本体が式であり、が非非同期で、戻り値の型が void 以外の場合、またはが async で戻り値の型がある場合、の各パラメーターには、 F F D T F 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 D Task<T> の各パラメーターには、に対応するパラメーターの型が指定されている場合、 F D F 到達できないエンドポイントを持つ有効なステートメントブロック (wrt block) を使用し 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 int x+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.

同様に、 Func<int,double> x+1 (型の) の結果は int 暗黙的に型に変換できるため、2番目の代入では匿名関数がデリゲート型に正常に変換され 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# コンパイラで使用されるのと同じ原則に基づいていますが、これは必須の実装ではなく、可能な唯一の方法でもあります。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. これは、コンパイラによって生成されるクラスのフィールドにローカル変数を "hoisting" することによって実現できます。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); };
        }
    }
}

ここでは、別のブロックのローカル変数が独立した有効期間を持つことができるように、ローカルがキャプチャされた各ステートメントブロックに対して、コンパイラによって生成されるクラスが作成されます。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 (内部ステートメントブロックに対してコンパイラによって生成されるクラス) には、ローカル変数 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 メソッドグループとして分類される式が指定されて E D いる場合、では、 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. からへの暗黙の型変換が存在する場合は、 E D 変換のコンパイル時のアプリケーションがエラーなしで成功することは保証されません。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.

  • Mフォームのメソッド呼び出し (メソッドの呼び出し) に対応する1つのメソッドが選択され、 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 outformal_parameter_list の対応するパラメーターの型と修飾子 (または) を使用し D ます。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 、型、つまり、選択したメソッドとターゲットオブジェクトを参照する新しく作成されたデリゲートの値になります。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 型の値に変換する代入 D1The 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.

他の暗黙的な変換および明示的な変換と同様に、cast 演算子を使用してメソッドグループの変換を明示的に実行できます。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. 選択したメソッドがインスタンスメソッドで、ターゲットオブジェクトがの場合は、 null System.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.