변환Conversions

*Conversion _을 사용 하면 식을 특정 형식으로 처리할 수 있습니다.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 암시적으로 형식으로 처리 될 수 있습니다 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 변환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.

변환의 목적을 위해 object 및 형식은 dynamic 동일 하 게 간주 됩니다.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

항등 변환은 모든 형식에서 동일한 형식으로 변환 합니다.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 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 또는 decimal 입니다.From 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 또는 decimal 입니다.From 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 또는 decimal 입니다.From 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 기타 정수 계열 형식의 값이 자동으로 형식으로 변환 되지 않습니다 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 으로 변환 하 고 내부 형식이 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 로 변환 하 고 결과 (Nullable 형식)를 래핑하여 변환을 평가 합니다.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

Nullable이 아닌 값 형식에 대해 작동 하는 미리 정의 된 암시적 변환은 해당 형식의 nullable 형식에도 사용할 수 있습니다.Predefined implicit conversions that operate on non-nullable value types can also be used with nullable forms of those types. Nullable이 아닌 값 형식에서 nullable이 아닌 값 형식으로 변환 되는 미리 정의 된 암시적 id 및 숫자 변환 각각에 대해 S T 다음과 같은 암시적 nullable 변환이 있습니다.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?.

에서로의 기본 변환을 기반으로 하는 암시적 nullable 변환의 평가는 다음과 S T 같이 진행 됩니다.Evaluation of an implicit nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • Nullable이에서로 변환 되 면이 고, 그렇지 않으면입니다 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 래핑 (Nullable 형식) 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?.
  • 에서로의 nullable 변환이 인 경우 변환은에서로의 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리터럴에서 nullable 형식으로의 암시적 변환이 있습니다.An implicit conversion exists from the null literal to any nullable type. 이 변환은 지정 된 nullable 형식의 null 값 (nullable 형식)을 생성 합니다.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 T 제공 되는 class_type에서 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 T 제공 되는 interface_type에서 S 파생 됩니다 T .From any interface_type S to any interface_type T, provided S is derived from T.
  • 요소 형식을 사용 하는 array_type S 에서 SE 요소 형식을 사용 하는 array_type 에 대해 T 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:
    • S 및는 T 요소 형식만 다릅니다.S and T differ only in element type. 즉, 및에 S T 는 동일한 수의 차원이 있습니다.In other words, S and T have the same number of dimensions.
    • SETE 는 모두 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 또는 참조가 있는 경우 단일 차원 배열 형식에서 및 해당 기본 인터페이스로 변환 S T 합니다.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_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.
  • T Reference_type 에 대 한 암시적 id 또는 참조 변환이 있고로의 id 변환이 있는 경우 모든 reference_type에서 reference_type으로 변환 T0 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.
  • 인터페이스 또는 T 대리자 형식에 대 한 암시적 id 또는 참조 변환이 있고이 T0 T0 에 대 한 가변성 (variance변환)이 인 경우 모든 reference_type에서 인터페이스 또는 대리자 형식으로 변환 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 변환Boxing conversions

Boxing 변환을 사용 하면 value_type 를 참조 형식으로 암시적으로 변환할 수 있습니다.A boxing conversion permits a value_type to be implicitly converted to a reference type. 모든 non_nullable_value_type 에서로,에서로 object non_nullable_value_type 구현 되는 dynamic System.ValueType 모든 interface_type 에 대 한 boxing 변환이 있습니다.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.

Boxing 변환이 기본 non_nullable_value_type 에서 참조 형식으로 존재 하는 경우에만 nullable_type 에서 참조 형식으로의 boxing 변환이 있습니다.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 인터페이스 형식으로의 boxing 변환이 있고 I0 로의 id 변환이 있는 경우 해당 형식에 대 한 boxing 변환이 있습니다 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 또는 대리자 형식에 대 한 boxing 변환을 포함 하 I0I0 분산 변환 가능 (분산 변환)이 인 경우 인터페이스 형식에 대 한 boxing 변환을 포함 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 값을 Boxing 하는 것은 개체 인스턴스를 할당 하 고 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 모든 구조체 (상속)의 기본 클래스 이므로 형식에 boxing 될 수 있습니다.A struct can be boxed to the type System.ValueType, since that is a base class for all structs (Inheritance).

Nullable_type 의 값 Boxing은 다음과 같이 진행 됩니다.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.
  • 그렇지 않으면 결과는 래핑 해제에 의해 생성 된 boxed에 대 한 참조 T 이며 소스 값을 boxing 합니다.Otherwise, the result is a reference to a boxed T produced by unwrapping and boxing the source value.

Boxing 변환은 boxing 변환에 자세히 설명 되어 있습니다.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. 변환이 없는 경우 런타임 예외가 throw 됩니다.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 되지 않습니다 int .A conversion is found to string but not to int.

암시적 상수 식 변환Implicit constant expression conversions

암시적 상수 식 변환은 다음과 같은 변환을 허용 합니다.An implicit constant expression conversion permits the following conversions:

  • int sbyte byte short ushort uint ulong Constant_expression 의 값이 대상 형식의 범위 내에 있는 경우 형식의 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.
  • long ulong Constant_expression 의 값이 음수가 아닌 경우 형식의 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 모든 인터페이스로 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 이 값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.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 로의 유효한 인터페이스 I T 집합 및에서 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 이 값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.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 가 값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.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 참조 형식으로의 암시적 변환이 있고에 대 한 id 변환이 있는 경우에서 참조 형식으로 S0 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 이 값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.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이 참조 형식으로 알려지지 않은 경우 위의 변환은 boxing 변환 (boxing 변환)으로 분류 됩니다.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.
  • 명시적 nullable 변환.Explicit nullable conversions.
  • 명시적 참조 변환입니다.Explicit reference conversions.
  • 명시적 인터페이스 변환입니다.Explicit interface conversions.
  • Unboxing 변환.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 또는 char 입니다.From sbyte to byte, ushort, uint, ulong, or char.
  • 부터 byte sbyte 및 사이 char 입니다.From byte to sbyte and char.
  • 부터,,,, short sbyte byte ushort uint ulong 또는 char 입니다.From 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 또는 char 입니다.From 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).

명시적 숫자 변환으로 인해 정보가 손실 되거나 예외가 throw 될 수 있습니다.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 소스 피연산자의 값이 대상 형식의 범위를 벗어나면이 throw 됩니다.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.
      • 소스 형식이 대상 형식보다 큰 경우 소스 값은 가장 중요한 비트인 해당 "extra"를 삭제함으로써 잘립니다.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.
      • 소스 형식이 대상 형식보다 작은 경우 소스 값은 대상 형식과 크기가 같도록 부호 확장 또는 0 확장 중 하나입니다.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. 부호 확장은 소스 형식이 서명된 경우 사용되며, 소스 형식이 서명되지 않은 경우 0 확장이 사용됩니다.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 이 throw 됩니다.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 이 throw 됩니다.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이 throw됩니다.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.
  • 에서로 변환 하는 경우 double float 값은 double 가장 가까운 값으로 반올림 됩니다 float .For a conversion from double to float, the double value is rounded to the nearest float value. double값이 너무 작아서로 나타낼 수 없는 경우 float 결과는 0 또는 음수 0이 됩니다.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 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, infinity 또는 너무 커서로 나타낼 수 없으면 decimal System.OverflowException 이 throw 됩니다.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. 이 변환으로 인해 전체 자릿수가 손실 될 수 있지만 예외가 throw 되지 않습니다.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.

두 형식 간의 명시적 열거형 변환은 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 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

명시적 nullable 변환은 null을 허용 하지 않는 값 형식에 대해 작동 하는 미리 정의 된 명시적 변환을 이러한 형식의 nullable 형식에도 사용할 수 있도록 허용 합니다.Explicit nullable conversions permit predefined explicit conversions that operate on non-nullable value types to also be used with nullable forms of those types. Nullable이 아닌 값 형식에서 nullable이 아닌 값 형식 S T (id 변환, 암시적 숫자 변환, 암시적 열거형 변환, 명시적 숫자 변환명시적 열거형 변환)으로 변환 하는 미리 정의 된 명시적 변환 각각에 대해 다음과 같은 nullable 변환이 있습니다.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? 변환 T 입니다.An explicit conversion from S? to T.

에서로의 기본 변환을 기반으로 하는 nullable 변환의 평가는 다음과 S T 같이 진행 됩니다.Evaluation of a nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • Nullable이에서로 변환 되 면이 고, 그렇지 않으면입니다 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?.
  • 에서로의 nullable 변환이 인 경우 변환은에서로의 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?.
  • Nullable이에서로 변환 되는 경우 변환은에서로의 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을 허용 하는 값을 래핑 해제 하려는 시도는 값이 인 경우 예외를 throw 합니다 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_typeFrom 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 에서 interface_type로 제공 되며, 제공 된 S 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_typeT S 파생 되지 않습니다 T .From any interface_type S to any interface_type T, provided S is not derived from T.
  • 요소 형식을 사용 하는 array_type S 에서 SE 요소 형식을 사용 하는 array_type 에 대해 T 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:
    • S 및는 T 요소 형식만 다릅니다.S and T differ only in element type. 즉, 및에 S T 는 동일한 수의 차원이 있습니다.In other words, S and T have the same number of dimensions.
    • SETE 는 모두 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> 에서로의 명시적 참조가 있는 경우 단일 차원 배열 형식에서 및 해당 기본 인터페이스로 변환 S T 합니다.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> T[] 로의 명시적 id 또는 참조 변환이 있는 경우 및 해당 기본 인터페이스에서 단일 차원 배열 형식으로 S TFrom 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.
  • 참조 형식에 대 한 명시적 참조 변환이 있고 id 변환이 있는 경우 참조 형식에서 참조 형식으로 변환 T T0 T0 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 경우 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 D .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가 공변 (covariant) 이면에서로의 암시적 또는 명시적 id 또는 참조 변환이 Si 있습니다 Ti .If Xi is covariant, then there is an implicit or explicit identity or reference conversion from Si to Ti.
    • Xi가 반공 변 (contravariant) 이면 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 이 이거나, 소스 피연산자가 참조 하는 개체의 실제 형식이 암시적 참조 변환 (암시적 참조 변환) 또는 Boxing 변환 (boxing변환)을 통해 대상 형식으로 변환 될 수 있는 형식 이어야 합니다.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 이 throw 됩니다.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 변환Unboxing conversions

Unboxing 변환을 사용 하면 참조 형식을 value_type 로 명시적으로 변환할 수 있습니다.An unboxing conversion permits a reference type to be explicitly converted to a value_type. Unboxing 변환은 형식 object dynamic 및 모든 System.ValueType interface_type non_nullable_value_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 로 unboxing 될 수 있습니다.Furthermore type System.Enum can be unboxed to any enum_type.

참조 형식에서 nullable_type 의 기본 non_nullable_value_type 에 대 한 unboxing 변환이 있는 경우 참조 형식에서 nullable_type unboxing 변환이 있습니다.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 인터페이스 형식에서 unboxing 변환이 있고 I0 에 대 한 id 변환이 있는 경우 인터페이스 형식에서 unboxing 변환이 포함 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 또는 대리자 형식에서 unboxing 변환을 포함 하 고 가변성 (variance)을로 변환할 수 있는 경우 인터페이스 형식에서 unboxing 변환을 가집니다 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).

Unboxing 작업은 개체 인스턴스가 지정 된 value_type 의 boxing 된 값 인지 먼저 확인 한 다음 인스턴스 밖의 값을 복사 하는 것으로 구성 됩니다.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. Unboxing nullable_type 에 대 한 null 참조는 nullable_type 의 null 값을 생성 합니다.Unboxing a null reference to a nullable_type produces the null value of the nullable_type. 구조체는 System.ValueType 모든 구조체 (상속)의 기본 클래스 이므로 형식에서 unboxing 될 수 있습니다.A struct can be unboxed from the type System.ValueType, since that is a base class for all structs (Inheritance).

Unboxing 변환은 unboxing 변환에 자세히 설명 되어 있습니다.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. 변환이 없는 경우 런타임 예외가 throw 됩니다.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:

  • 의 유효한 기본 클래스에서 CT T 및의 기본 클래스에서 CTFrom the effective base class C of T to T and from any base class of C to T. 런타임에 T 이 값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.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 이 값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.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 로의 I 암시적 변환이 아직 없는 경우에서 interface_type T I .From T to any interface_type I provided there is not already an implicit conversion from T to I. 런타임에 T 이 값 형식인 경우 변환은 boxing 변환으로 실행 된 다음 명시적 참조 변환으로 실행 됩니다.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). 런타임에 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 가 값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.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이 참조 형식으로 알려지지 않은 경우 위의 변환은 unboxing 변환 (unboxing 변환)으로 분류 됩니다.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 는로 직접 변환할 수 없으므로 런타임에 예외가 throw 됩니다 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 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 또는가 nullable 형식이 면를 사용 하 여 S 기본 형식을 참조 하 고, 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 S .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

Nullable이 아닌 값 형식에서 nullable이 아닌 값 형식으로 변환 하는 사용자 정의 변환 연산자가 지정 된 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.

가장 구체적인 사용자 정의 변환 연산자가 식별 되 면 사용자 정의 변환의 실제 실행에는 다음 세 단계가 포함 됩니다.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 T .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:

  • 표준 암시적 변환 (표준 암시적변환)이 형식에서 A 형식으로 존재 하는 경우 B 와가 둘 다 A B interface_type 않으면 A 가 *포함 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.
  • 형식 집합에서 가장 많이 포함 된 형식은 집합의 다른 모든 형식을 포함 하는 한 가지 형식입니다.The most encompassing type in a set of types is the one type that encompasses all other types in the set. 다른 모든 형식을 포함 하는 단일 형식이 없는 경우에는 집합에 가장 많은 형식이 포함 되지 않습니다.If no single type encompasses all other types, then the set has no most encompassing type. 보다 직관적인 용어로, 가장 많이 사용 되는 형식은 집합에서 "가장 큰" 형식입니다. 즉, 각각의 다른 형식이 암시적으로 변환 될 수 있는 형식입니다.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. 보다 직관적인 용어에서 가장 많이 사용 되는 형식은 집합의 "가장 작은" 형식으로, 다른 형식으로 암시적으로 변환할 수 있는 형식입니다.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 가 nullable 형식이 고, S0T0 해당 기본 형식이 면이 고, 그렇지 않으면 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 로 변환 하는 연산자가 인 경우 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. 가장 일치 하는 형식을 정확히 하나 찾을 수 없으면 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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 되 면 TXT 입니다.If 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. 가장 많이 포괄 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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에에서로 변환 하는 정확히 하나의 사용자 정의 변환 연산자가 포함 된 경우 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 에서로 변환 하는 리프트 변환 연산자를 정확히 한 개 포함 하는 경우 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 가 nullable 형식이 고, S0T0 해당 기본 형식이 면이 고, 그렇지 않으면 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 로 변환 하는 연산자가 인 경우 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. 가장 많이 포괄 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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 되 면 TXT 입니다.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. 가장 많이 포괄 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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에에서로 변환 하는 정확히 하나의 사용자 정의 변환 연산자가 포함 된 경우 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 에서로 변환 하는 리프트 변환 연산자를 정확히 한 개 포함 하는 경우 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 포함 된 경우 및에는 D F 동일한 수의 매개 변수가 있습니다.If F contains an anonymous_function_signature, then D and F have the same number of parameters.
  • Fanonymous_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 반환 형식이 이거나 async 이며 반환 형식이 있는 경우의 F D Task 각 매개 변수에는의 F 해당 매개 변수 형식이 지정 되 고 D ,의 본문은 F statement_expression (식 문)으로 허용 되는 유효한 식 (wrt Expressions)입니다.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 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 반환 형식을 포함 T 하거나 비동기 이며 반환 형식이 있는 경우의 F D Task<T> 각 매개 변수에는의 F 해당 매개 변수 형식이 지정 되 고 D ,의 본문은 F 로 암시적으로 변환할 수 있는 유효한 식 (wrt Expressions)입니다 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 -비정적 반환 형식 T 이거나 F 비동기 이며 D 반환 형식이 있는 Task<T> 경우의 각 매개 변수에는의 F 해당 매개 변수 형식이 지정 되 고 D ,의 본문 Freturn 문이 암시적으로 변환할 수 있는 식을 지정 하는 연결할 수 없는 끝점이 있는 유효한 문 블록 (wrt 블록)입니다 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 으로 암시적으로 변환할 수 있기 때문에 두 번째 할당은 익명 함수를 대리자 형식으로 변환 합니다 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.

그러나를 지정 하는 경우 형식에 대 한의 결과를 형식 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.

네 번째 할당에서는 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.

익명 함수에서 생성 된 대리자의 호출 목록에는 단일 항목이 포함 되어 있습니다.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. 특히, 대리자의 대상 개체가 인지 null , this 바깥쪽 함수 멤버의 값 또는 다른 개체 인지는 지정 되지 않습니다.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));
        ...
    }
}

두 익명 함수 대리자는 동일한 (비어 있는) 캡처된 외부 변수 집합을 포함 하 고, 익명 함수가 의미상 동일 하기 때문에 컴파일러는 대리자가 동일한 대상 메서드를 참조 하도록 허용 합니다.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 다른 수명으로 두 개의 지역 변수를 캡처합니다.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. 대리자 형식 DE 메서드 그룹으로 분류 된 식이 지정 된 E D 경우 다음에 설명 된 것 처럼에서로의 암시적 변환은에서로 E 의 매개 변수 형식 및 한정자를 사용 하 여 생성 된 인수 목록에 대 한 표준 형식 (적용 가능한 함수 멤버)이 하나 이상 포함 되어 있는 경우를로 변환 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다음을 수정 하 여 폼의 메서드 호출 (메서드 호출)에 해당 하는 단일 메서드가 선택 됩니다 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. 그렇지 않으면 알고리즘은와 동일한 수의 매개 변수를 포함 하는 최상의 단일 메서드를 생성 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 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. 선택한 메서드가 인스턴스 메서드이 고 대상 개체가 인 경우 null System.NullReferenceException 이 throw 되 고 추가 단계가 실행 되지 않습니다.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 이면 boxing 작업 (boxing 변환)을 수행 하 여 값을 개체로 변환 합니다 .이 개체는 대상 개체가 됩니다.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 이 throw 되 고 추가 단계가 실행 되지 않습니다.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.