변환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. 변환은 암시적 이거나 명시적일 수 있으며,이는 명시적 캐스트가 필요한 지 여부를 결정 합니다.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
- 암시적 nullable 변환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
를 바꿀 때 동일 하 게 생성 된 형식 사이에 있습니다.Becauseobject
anddynamic
are considered equivalent there is an identity conversion betweenobject
anddynamic
, and between constructed types that are the same when replacing all occurrences ofdynamic
withobject
.
암시적 숫자 변환Implicit numeric conversions
암시적 숫자 변환은 다음과 같습니다.The implicit numeric conversions are:
sbyte
에서short
,int
,long
,float
,double
또는decimal
입니다.Fromsbyte
toshort
,int
,long
,float
,double
, ordecimal
.byte
에서short
,ushort
,int
,uint
,long
,ulong
,float
,double
또는decimal
입니다.Frombyte
toshort
,ushort
,int
,uint
,long
,ulong
,float
,double
, ordecimal
.short
에서int
,long
,float
,double
또는decimal
입니다.Fromshort
toint
,long
,float
,double
, ordecimal
.ushort
에서int
,uint
,long
,ulong
,float
,double
또는decimal
입니다.Fromushort
toint
,uint
,long
,ulong
,float
,double
, ordecimal
.int
에서long
,float
,double
또는decimal
입니다.Fromint
tolong
,float
,double
, ordecimal
.uint
에서long
,ulong
,float
,double
또는decimal
입니다.Fromuint
tolong
,ulong
,float
,double
, ordecimal
.long
에서float
,double
또는decimal
입니다.Fromlong
tofloat
,double
, ordecimal
.ulong
에서float
,double
또는decimal
입니다.Fromulong
tofloat
,double
, ordecimal
.char
에서ushort
,int
,uint
,long
,ulong
,float
,double
또는decimal
입니다.Fromchar
toushort
,int
,uint
,long
,ulong
,float
,double
, ordecimal
.float
에서double
로Fromfloat
todouble
.
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.
암시적 nullable 변환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이 아닌 값 형식에서 S
T
nullable이 아닌 값 형식으로 변환 하는 미리 정의 된 암시적 id 및 숫자 변환 각각에 대해 다음과 같은 암시적 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 fromS?
toT?
.S
에서T?
로의 암시적 변환입니다.An implicit conversion fromS
toT?
.
S
에서 T
로의 기본 변환을 기반으로 하는 암시적 nullable 변환의 평가는 다음과 같이 진행 됩니다.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 fromS?
toT?
:- 원본 값이 null 인 경우 (
HasValue
속성이 false 인 경우) 결과는T?
형식의 null 값입니다.If the source value is null (HasValue
property is false), the result is the null value of typeT?
. - 그렇지 않으면 변환이
S?
에서S
로 차례로 계산 된 후S
에서T
로의 기본 변환과T
에서T?
로 래핑 (Nullable 형식)이 차례로 수행 됩니다.Otherwise, the conversion is evaluated as an unwrapping fromS?
toS
, followed by the underlying conversion fromS
toT
, followed by a wrapping (Nullable types) fromT
toT?
.
- 원본 값이 null 인 경우 (
S
에서T?
로의 nullable 변환이 수행 되는 경우 변환은S
에서T
로의 기본 변환으로 계산 된 후T
에서T?
로 래핑 됩니다.If the nullable conversion is fromS
toT?
, the conversion is evaluated as the underlying conversion fromS
toT
followed by a wrapping fromT
toT?
.
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
으로dynamic
합니다.From any reference_type toobject
anddynamic
. - 모든 class_type
S
에서 class_typeT``S
T
에서 파생 됩니다.From any class_typeS
to any class_typeT
, providedS
is derived fromT
. - 모든 class_type
S
에서 interface_typeT``S
를 구현T
.From any class_typeS
to any interface_typeT
, providedS
implementsT
. - 모든 interface_type
S
에서 interface_typeT``S
T
에서 파생 됩니다.From any interface_typeS
to any interface_typeT
, providedS
is derived fromT
. - 요소 형식이
T
인 array_typeTE``SE
요소 형식이 인 array_typeS
에서 다음 모두에 해당 하는 경우입니다.From an array_typeS
with an element typeSE
to an array_typeT
with an element typeTE
, provided all of the following are true:S
및T
는 요소 형식만 다릅니다.S
andT
differ only in element type. 즉,S
및T
에 같은 수의 차원이 있습니다.In other words,S
andT
have the same number of dimensions.SE
와TE
는 모두 reference_types입니다.BothSE
andTE
are reference_types.SE
에서TE
로의 암시적 참조 변환이 있습니다.An implicit reference conversion exists fromSE
toTE
.
- 모든 array_type 에서
System.Array
및 구현 하는 인터페이스입니다.From any array_type toSystem.Array
and the interfaces it implements. S
에서T
로의 암시적 id 또는 참조 변환이 있는 경우 단일 차원 배열 형식에서System.Collections.Generic.IList<T>
및 해당 기본 인터페이스를S[]
합니다.From a single-dimensional array typeS[]
toSystem.Collections.Generic.IList<T>
and its base interfaces, provided that there is an implicit identity or reference conversion fromS
toT
.- 모든 delegate_type 에서
System.Delegate
및 구현 하는 인터페이스입니다.From any delegate_type toSystem.Delegate
and the interfaces it implements. - Null 리터럴에서 모든 reference_type합니다.From the null literal to any reference_type.
- Reference_type
T0
에 대 한 암시적 id 또는 참조 변환이 있는 경우 모든 reference_type 에서 reference_typeT
하 고T0
에 대 한 id 변환이T
있습니다.From any reference_type to a reference_typeT
if it has an implicit identity or reference conversion to a reference_typeT0
andT0
has an identity conversion toT
. - 인터페이스 또는 대리자 형식에 대 한 암시적 id 또는 참조
T0
변환이 있는 경우 모든 reference_type 에서 인터페이스 또는 대리자 형식으로T
하 고T0
분산 변환 가능 (분산 변환)을T
합니다.From any reference_type to an interface or delegate typeT
if it has an implicit identity or reference conversion to an interface or delegate typeT0
andT0
is variance-convertible (Variance conversion) toT
. - 참조 형식으로 알려진 형식 매개 변수와 관련 된 암시적 변환Implicit conversions involving type parameters that are known to be reference types. 형식 매개 변수와 관련 된 암시적 변환에 대 한 자세한 내용은 형식 매개 변수와 관련 된 암시적 변환 을 참조 하세요.See Implicit conversions involving type parameters for more details on implicit conversions involving type parameters.
암시적 참조 변환은 항상 성공할 수 있는 것으로 입증 될 수 있는 reference_type간의 변환입니다. 따라서 런타임에는 검사가 필요 하지 않습니다.The implicit reference conversions are those conversions between reference_types that can be proven to always succeed, and therefore require no checks at run-time.
참조 변환은 암시적 또는 명시적으로 변환 되는 개체의 참조 id를 변경 하지 않습니다.Reference conversions, implicit or explicit, never change the referential identity of the object being converted. 즉, 참조 변환은 참조의 형식을 변경할 수 있지만 참조 되는 개체의 형식이 나 값을 변경 하지 않습니다.In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.
Boxing 변환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
및 dynamic
에 대 한 boxing 변환은 System.ValueType
및 interface_type에서 구현 된 모든 non_nullable_value_type 에 대해 존재 합니다.A boxing conversion exists from any non_nullable_value_type to object
and dynamic
, to System.ValueType
and to any interface_type implemented by the non_nullable_value_type. 또한 enum_type System.Enum
형식으로 변환할 수 있습니다.Furthermore an enum_type can be converted to the type System.Enum
.
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.
값 형식에는 인터페이스 형식에 I0
대 한 boxing 변환이 있고 I0
에서 I
로의 id 변환이 있는 경우 I
인터페이스 형식으로의 boxing 변환이 있습니다.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
.
값 형식에는 인터페이스 또는 대리자 I0
형식에 대 한 boxing 변환이 있는 경우 I
인터페이스 형식에 대 한 boxing 변환이 있으며, I0
는 가변성 (variance변환)을 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 boxedT
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:
short
값이 대상 형식의 범위 내에 있는 경우int
형식의 constant_expression (상수 식)를sbyte
,byte
,ushort
,uint
,ulong
또는 constant_expression 형식으로 변환할 수 있습니다.A constant_expression (Constant expressions) of typeint
can be converted to typesbyte
,byte
,short
,ushort
,uint
, orulong
, provided the value of the constant_expression is within the range of the destination type.- Constant_expression 의 값이 음수가 아닌 경우
long
형식의 constant_expressionulong
형식으로 변환할 수 있습니다.A constant_expression of typelong
can be converted to typeulong
, provided the value of the constant_expression is not negative.
형식 매개 변수와 관련 된 암시적 변환Implicit conversions involving type parameters
지정 된 형식 매개 변수에 대 한 다음과 같은 암시적 변환이 T
됩니다.The following implicit conversions exist for a given type parameter T
:
T
에서 유효한 기본 클래스C
,T
에서C
의 기본 클래스,T
에서 구현 된 모든 인터페이스로C
.FromT
to its effective base classC
, fromT
to any base class ofC
, and fromT
to any interface implemented byC
. 런타임에T
값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.At run-time, ifT
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
에서 인터페이스 형식으로T
의 유효 인터페이스 집합에I
하 고T
에서I
의 기본 인터페이스로 합니다.FromT
to an interface typeI
inT
's effective interface set and fromT
to any base interface ofI
. 런타임에T
값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.At run-time, ifT
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
(형식 매개 변수 제약 조건)에 따라 달라 집니다.FromT
to a type parameterU
, providedT
depends onU
(Type parameter constraints). 런타임에U
값 형식인 경우T
및U
는 항상 동일한 형식이 고 변환이 수행 되지 않습니다.At run-time, ifU
is a value type, thenT
andU
are necessarily the same type and no conversion is performed. 그렇지 않고T
값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.Otherwise, ifT
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 toT
, providedT
is known to be a reference type. S0
참조 형식으로의 암시적 변환이 있고S0
에서S
로의 id 변환이 있는 경우T
에서 참조 형식으로I
.FromT
to a reference typeI
if it has an implicit conversion to a reference typeS0
andS0
has an identity conversion toS
. 런타임에 변환은S0
변환과 동일한 방식으로 실행 됩니다.At run-time the conversion is executed the same way as the conversion toS0
.- 인터페이스 또는 대리자
I0
형식으로의 암시적 변환이 있고I0
분산이I
(분산 변환)로 변환 가능한 경우T
에서 인터페이스 형식으로I
.FromT
to an interface typeI
if it has an implicit conversion to an interface or delegate typeI0
andI0
is variance-convertible toI
(Variance conversion). 런타임에T
값 형식인 경우 변환은 boxing 변환으로 실행 됩니다.At run-time, ifT
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
입니다.Fromsbyte
tobyte
,ushort
,uint
,ulong
, orchar
.byte
에서sbyte
및char
합니다.Frombyte
tosbyte
andchar
.short
에서sbyte
,byte
,ushort
,uint
,ulong
또는char
입니다.Fromshort
tosbyte
,byte
,ushort
,uint
,ulong
, orchar
.ushort
에서sbyte
,byte
,short
또는char
입니다.Fromushort
tosbyte
,byte
,short
, orchar
.int
에서sbyte
,byte
,short
,ushort
,uint
,ulong
또는char
입니다.Fromint
tosbyte
,byte
,short
,ushort
,uint
,ulong
, orchar
.uint
에서sbyte
,byte
,short
,ushort
,int
또는char
입니다.Fromuint
tosbyte
,byte
,short
,ushort
,int
, orchar
.long
에서sbyte
,byte
,short
,ushort
,int
,uint
,ulong
또는char
입니다.Fromlong
tosbyte
,byte
,short
,ushort
,int
,uint
,ulong
, orchar
.ulong
에서sbyte
,byte
,short
,ushort
,int
,uint
,long
또는char
입니다.Fromulong
tosbyte
,byte
,short
,ushort
,int
,uint
,long
, orchar
.char
에서sbyte
,byte
또는short
입니다.Fromchar
tosbyte
,byte
, orshort
.float
에서sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
또는decimal
입니다.Fromfloat
tosbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
, ordecimal
.double
에서sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
또는decimal
.Fromdouble
tosbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
, ordecimal
.decimal
에서sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
또는double
.Fromdecimal
tosbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
, ordouble
.
명시적 변환에는 모든 암시적 및 명시적 숫자 변환이 포함 되므로 캐스트 식 (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 achecked
context, the conversion succeeds if the value of the source operand is within the range of the destination type, but throws aSystem.OverflowException
if the value of the source operand is outside the range of the destination type.unchecked
컨텍스트에서는 변환이 항상 성공 하 고 다음과 같이 진행 합니다.In anunchecked
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 fromdecimal
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, aSystem.OverflowException
is thrown.float
또는double
에서 정수 계열 형식으로 변환 하는 경우 처리는 변환이 수행 되는 오버플로 검사 컨텍스트 (checked 및 unchecked 연산자)에 따라 달라 집니다.For a conversion fromfloat
ordouble
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 achecked
context, the conversion proceeds as follows:- 피연산자의 값이 NaN 또는 무한 인 경우
System.OverflowException
이 throw 됩니다.If the value of the operand is NaN or infinite, aSystem.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, aSystem.OverflowException
is thrown.
- 피연산자의 값이 NaN 또는 무한 인 경우
unchecked
컨텍스트에서는 변환이 항상 성공 하 고 다음과 같이 진행 합니다.In anunchecked
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 fromdouble
tofloat
, thedouble
value is rounded to the nearestfloat
value.double
값이 너무 작아float
나타낼 수 없는 경우 결과는 0 또는 음수 0이 됩니다.If thedouble
value is too small to represent as afloat
, the result becomes positive zero or negative zero.double
값이 너무 커서float
나타낼 수 없는 경우 결과는 양의 무한대 또는 음의 무한대가 됩니다.If thedouble
value is too large to represent as afloat
, the result becomes positive infinity or negative infinity.double
값이 NaN 이면 결과도 NaN입니다.If thedouble
value is NaN, the result is also NaN.float
또는double
에서decimal
로 변환 하는 경우 소스 값은decimal
표현으로 변환 되 고 필요한 경우 28 번째 소수 자릿수 뒤의 가장 가까운 숫자로 반올림 됩니다 (10 진수 형식).For a conversion fromfloat
ordouble
todecimal
, the source value is converted todecimal
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 adecimal
, the result becomes zero. 원본 값이 NaN, infinity 또는 너무 커서decimal
나타낼 수 없는 경우System.OverflowException
throw 됩니다.If the source value is NaN, infinity, or too large to represent as adecimal
, aSystem.OverflowException
is thrown.decimal
에서float
또는double
으로 변환 하는 경우decimal
값은 가장 가까운double
또는float
값으로 반올림 됩니다.For a conversion fromdecimal
tofloat
ordouble
, thedecimal
value is rounded to the nearestdouble
orfloat
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 합니다.Fromsbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
, ordecimal
to any enum_type.- 모든 enum_type 에서
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
또는decimal
입니다.From any enum_type tosbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
, ordecimal
. - 모든 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. 예를 들어 int
의 및 기본 형식으로 된 enum_type E
경우 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
.
명시적 nullable 변환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이 아닌 값 형식에서 S
nullable이 아닌 값 형식 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 fromS?
toT?
.S
에서T?
로의 명시적 변환입니다.An explicit conversion fromS
toT?
.S?
에서T
로의 명시적 변환입니다.An explicit conversion fromS?
toT
.
S
에서 T
로의 기본 변환을 기반으로 하는 nullable 변환의 평가는 다음과 같이 진행 됩니다.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 fromS?
toT?
:- 원본 값이 null 인 경우 (
HasValue
속성이 false 인 경우) 결과는T?
형식의 null 값입니다.If the source value is null (HasValue
property is false), the result is the null value of typeT?
. - 그렇지 않은 경우 변환은
S?
에서S
로 차례로 계산 된 다음S
에서T
로의 기본 변환과T
에서T?
로 래핑 됩니다.Otherwise, the conversion is evaluated as an unwrapping fromS?
toS
, followed by the underlying conversion fromS
toT
, followed by a wrapping fromT
toT?
.
- 원본 값이 null 인 경우 (
S
에서T?
로의 nullable 변환이 수행 되는 경우 변환은S
에서T
로의 기본 변환으로 계산 된 후T
에서T?
로 래핑 됩니다.If the nullable conversion is fromS
toT?
, the conversion is evaluated as the underlying conversion fromS
toT
followed by a wrapping fromT
toT?
.S?
에서T
로의 nullable 변환이 수행 되는 경우 변환은S?
에서S
로, 그리고 그 다음에S
에서T
로의 기본 변환이 오는 래핑 해제으로 평가 됩니다.If the nullable conversion is fromS?
toT
, the conversion is evaluated as an unwrapping fromS?
toS
followed by the underlying conversion fromS
toT
.
Null을 허용 하는 값을 래핑 해제 하려는 시도는 값이 null
경우 예외를 throw 합니다.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
에서 다른 reference_typedynamic
.Fromobject
anddynamic
to any other reference_type.- 모든 class_type
S
에서 class_typeT
에 대 한S
기본 클래스T
제공 됩니다.From any class_typeS
to any class_typeT
, providedS
is a base class ofT
. - 모든 class_type
S
에서 interface_typeT
으로 제공S
봉인 되지 않고S
을 구현 하지 않습니다.From any class_typeS
to any interface_typeT
, providedS
is not sealed and providedS
does not implementT
. - 모든 interface_type
S
에서 class_typeT``T
T
을 구현 하는S
를 봉인 하거나 제공 하지 않습니다.From any interface_typeS
to any class_typeT
, providedT
is not sealed or providedT
implementsS
. - 모든 interface_type
S
에서 interface_typeT``S
T
에서 파생 되지 않습니다.From any interface_typeS
to any interface_typeT
, providedS
is not derived fromT
. - 요소 형식이
T
인 array_typeTE``SE
요소 형식이 인 array_typeS
에서 다음 모두에 해당 하는 경우입니다.From an array_typeS
with an element typeSE
to an array_typeT
with an element typeTE
, provided all of the following are true:S
및T
는 요소 형식만 다릅니다.S
andT
differ only in element type. 즉,S
및T
에 같은 수의 차원이 있습니다.In other words,S
andT
have the same number of dimensions.SE
와TE
는 모두 reference_types입니다.BothSE
andTE
are reference_types.SE
에서TE
로의 명시적 참조 변환이 있습니다.An explicit reference conversion exists fromSE
toTE
.
System.Array
에서 array_type하는 인터페이스를 구현 합니다.FromSystem.Array
and the interfaces it implements to any array_type.S
에서T
로 명시적으로 참조를 변환 하는 경우 단일 차원 배열 형식에서System.Collections.Generic.IList<T>
및 해당 기본 인터페이스를S[]
합니다.From a single-dimensional array typeS[]
toSystem.Collections.Generic.IList<T>
and its base interfaces, provided that there is an explicit reference conversion fromS
toT
.S
에서T
로의 명시적 id 또는 참조 변환이 있는 경우System.Collections.Generic.IList<S>
및 해당 기본 인터페이스에서 단일 차원 배열 형식으로T[]
.FromSystem.Collections.Generic.IList<S>
and its base interfaces to a single-dimensional array typeT[]
, provided that there is an explicit identity or reference conversion fromS
toT
.System.Delegate
에서 delegate_type하는 인터페이스를 구현 합니다.FromSystem.Delegate
and the interfaces it implements to any delegate_type.- 참조 형식에 대 한 참조 형식에서 참조 형식으로의 명시적 참조 변환이 있는 경우
T
T0
T0
는 id 변환이T
.From a reference type to a reference typeT
if it has an explicit reference conversion to a reference typeT0
andT0
has an identity conversionT
. - 인터페이스 또는 대리자 형식에 대 한 명시적 참조 변환이 있는 경우
T
참조 형식에서 인터페이스 또는 대리자 형식으로의 명시적 참조 변환이 있는 경우에는T0
T
또는T
로 변환할 수 있는T0
(분산 변환)로 변환할 수 있습니다.From a reference type to an interface or delegate typeT
if it has an explicit reference conversion to an interface or delegate typeT0
and eitherT0
is variance-convertible toT
orT
is variance-convertible toT0
(Variance conversion). D<S1...Sn>
에서D<X1...Xn>
제네릭 대리자 형식인D<T1...Tn>
,D<S1...Sn>
은D<T1...Tn>
와 호환 되지 않으며, 각 형식 매개 변수에 대 한Xi
D
의에는 다음이 포함 됩니다.FromD<S1...Sn>
toD<T1...Tn>
whereD<X1...Xn>
is a generic delegate type,D<S1...Sn>
is not compatible with or identical toD<T1...Tn>
, and for each type parameterXi
ofD
the following holds:Xi
고정 이면Si
Ti
와 동일 합니다.IfXi
is invariant, thenSi
is identical toTi
.Xi
공변 (covariant) 인 경우Si
에서Ti
으로의 암시적 또는 명시적 id 또는 참조 변환이 있습니다.IfXi
is covariant, then there is an implicit or explicit identity or reference conversion fromSi
toTi
.Xi
반공 변 (contravariant) 인 경우Si
및Ti
는 동일한 참조 형식 이거나 둘 다입니다.IfXi
is contravariant, thenSi
andTi
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
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. 또한 모든 enum_type에 대 한 형식 System.Enum
를 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.
인터페이스 형식에서 I0
unboxing 변환이 있고 I0
에서 I
로의 id 변환이 있는 경우 값 형식 S
는 인터페이스 형식에서 unboxing 변환이 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
인터페이스 또는 대리자 I0
형식에서 unboxing 변환이 있는 경우 I
인터페이스 형식에서 unboxing 변환이 있는 경우 또는 I
로 변환할 수 있는 I0
분산 된 경우에는 I
(분산 변환)로 변환할 수 있습니다.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
. 그러나 명시적 동적 변환으로 C
d
변환은 런타임에 일시 중단 됩니다 .이로 인해 런타임 형식 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
의 기본 클래스에서T
로 합니다.From the effective base classC
ofT
toT
and from any base class ofC
toT
. 런타임에T
값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.At run-time, ifT
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 toT
. 런타임에T
값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.At run-time, ifT
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
로 암시적으로 변환 되지 않은 경우T
에서 interface_typeI
.FromT
to any interface_typeI
provided there is not already an implicit conversion fromT
toI
. 런타임에T
값 형식인 경우 변환은 boxing 변환으로 실행 된 다음 명시적 참조 변환을 실행 합니다.At run-time, ifT
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 parameterU
toT
, providedT
depends onU
(Type parameter constraints). 런타임에U
값 형식인 경우T
및U
는 항상 동일한 형식이 고 변환이 수행 되지 않습니다.At run-time, ifU
is a value type, thenT
andU
are necessarily the same type and no conversion is performed. 그렇지 않고T
값 형식인 경우 변환은 unboxing 변환으로 실행 됩니다.Otherwise, ifT
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
}
}
int
t
를 직접 명시적으로 변환 하는 것이 허용 되는 경우 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)
컴파일되지만 런타임에는 런타임에 예외를 throw 할 수 있습니다 .이는 boxing 된 int
long
으로 직접 변환할 수 없기 때문입니다.This code will now compile but executing X<int>.F(7)
would then throw an exception at run-time, since a boxed int
cannot be converted directly to a long
.
사용자 정의 명시적 변환User-defined explicit conversions
사용자 정의 명시적 변환은 선택적 표준 명시적 변환으로 구성 된 다음 사용자 정의 암시적 또는 명시적 변환 연산자의 실행으로 구성 되 고 그 뒤에 선택적 표준 명시적 변환이 적용 됩니다.A user-defined explicit conversion consists of an optional standard explicit conversion, followed by execution of a user-defined implicit or explicit conversion operator, followed by another optional standard explicit conversion. 사용자 정의 명시적 변환을 평가 하기 위한 정확한 규칙은 사용자 정의 명시적 변환 처리에 설명 되어 있습니다.The exact rules for evaluating user-defined explicit conversions are described in Processing of user-defined explicit conversions.
표준 변환Standard conversions
표준 변환은 사용자 정의 변환의 일부로 발생할 수 있는 미리 정의 된 변환입니다.The standard conversions are those pre-defined conversions that can occur as part of a user-defined conversion.
표준 암시적 변환Standard implicit conversions
다음 암시적 변환은 표준 암시적 변환으로 분류 됩니다.The following implicit conversions are classified as standard implicit conversions:
- Id 변환 (id 변환)Identity conversions (Identity conversion)
- 암시적 숫자 변환 (암시적 숫자 변환)Implicit numeric conversions (Implicit numeric conversions)
- 암시적 nullable 변환 (암시적 nullable 변환)Implicit nullable conversions (Implicit nullable conversions)
- 암시적 참조 변환 (암시적 참조 변환)Implicit reference conversions (Implicit reference conversions)
- Boxing 변환 (boxing 변환)Boxing conversions (Boxing conversions)
- 암시적 상수 식 변환 (암시적 동적 변환)Implicit constant expression conversions (Implicit dynamic conversions)
- 형식 매개 변수와 관련 된 암시적 변환 (형식 매개 변수와 관련 된 암시적 변환)Implicit conversions involving type parameters (Implicit conversions involving type parameters)
표준 암시적 변환은 사용자 정의 암시적 변환을 구체적으로 제외 합니다.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
형식으로 표준 명시적 변환이 존재 합니다.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
또는 T
nullable 형식이 면 S0
및 T0
에서 해당 기본 형식을 참조 합니다. 그렇지 않으면 S0
및 T0
가 각각 S
및 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:
S0
와T0
는 서로 다른 형식입니다.S0
andT0
are different types.S0
또는T0
는 연산자 선언이 발생 하는 클래스 또는 구조체 형식입니다.EitherS0
orT0
is the class or struct type in which the operator declaration takes place.S0
와T0
모두 interface_type아닙니다.NeitherS0
norT0
is an interface_type.- 사용자 정의 변환을 제외 하 고
S
T
또는T
에서S
로의 변환이 없습니다.Excluding user-defined conversions, a conversion does not exist fromS
toT
or fromT
toS
.
사용자 정의 변환에 적용 되는 제한 사항은 변환 연산자에 자세히 설명 되어 있습니다.The restrictions that apply to user-defined conversions are discussed further in Conversion operators.
리프트 변환 연산자Lifted conversion operators
Nullable이 아닌 값 형식 S
를 T
nullable이 아닌 값 형식으로 변환 하는 사용자 정의 변환 연산자가 지정 된 경우 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?
. 이 리프트 된 변환 연산자는 null 값 T
null 값 T?
으로 직접 변환 하는 경우를 제외 하 고 S
에서 T
로의 사용자 정의 변환, S?
에서 T?
로 래핑 S
S?
래핑 해제를 수행 합니다.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_types이 아니면A
를 포함 하 고B``B
를 포함 한다고 합니다.If a standard implicit conversion (Standard implicit conversions) exists from a typeA
to a typeB
, and if neitherA
norB
are interface_types, thenA
is said to be encompassed byB
, andB
is said to encompassA
. - 형식 집합에서 가장 많이 포함 된 형식은 집합의 다른 모든 형식을 포함 하는 한 가지 형식입니다.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 typesS0
andT0
.S
또는T
nullable 형식이 면S0
및T0
은 해당 기본 형식입니다. 그렇지 않으면S0
와T0
각각S
및T
와 같습니다.IfS
orT
are nullable types,S0
andT0
are their underlying types, otherwiseS0
andT0
are equal toS
andT
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 ofS0
(ifS0
is a class or struct), the base classes ofS0
(ifS0
is a class), andT0
(ifT0
is a class or struct). U
해당 하는 사용자 정의 및 리프트 변환 연산자 집합을 찾습니다.Find the set of applicable user-defined and lifted conversion operators,U
. 이 집합은S
를 사용 하는 형식에서T
에 의해 적용 되는 형식으로 변환 하는D
의 클래스 또는 구조체에서 선언 된 사용자 정의 및 리프트 된 암시적 변환 연산자로 구성 됩니다.This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs inD
that convert from a type encompassingS
to a type encompassed byT
.U
비어 있으면 변환이 정의 되지 않으며 컴파일 타임 오류가 발생 합니다.IfU
is empty, the conversion is undefined and a compile-time error occurs.U
에서 연산자의 가장 구체적인 원본 유형SX
를 찾습니다.Find the most specific source type,SX
, of the operators inU
:U
의 연산자 중 하나가S
변환 되 면SX
S
됩니다.If any of the operators inU
convert fromS
, thenSX
isS
.- 그렇지 않으면
SX
U
연산자의 결합 된 원본 형식 집합에서 가장 일치 하는 형식입니다.Otherwise,SX
is the most encompassed type in the combined set of source types of the operators inU
. 가장 일치 하는 형식을 정확히 하나 찾을 수 없으면 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.If exactly one most encompassed type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
U
에서 연산자의 가장 구체적인 대상 유형TX
를 찾습니다.Find the most specific target type,TX
, of the operators inU
:U
연산자 중 하나가T
으로 변환 되 면TX
T
됩니다.If any of the operators inU
convert toT
, thenTX
isT
.- 그렇지 않으면
U
연산자의 조합 된 대상 형식 집합에서 가장 많이 활용 되는 형식TX
입니다.Otherwise,TX
is the most encompassing type in the combined set of target types of the operators inU
. 가장 많이 포괄 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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:
SX
에서TX
로 변환 하는 정확히 하나의 사용자 정의 변환 연산자가U
에 포함 된 경우이는 가장 구체적인 변환 연산자입니다.IfU
contains exactly one user-defined conversion operator that converts fromSX
toTX
, then this is the most specific conversion operator.- 그렇지 않고
SX
에서TX
로 변환 하는 리프트 변환 연산자가U
포함 되어 있으면 가장 구체적인 변환 연산자입니다.Otherwise, ifU
contains exactly one lifted conversion operator that converts fromSX
toTX
, 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
로의 표준 암시적 변환이 수행 됩니다.IfS
is notSX
, then a standard implicit conversion fromS
toSX
is performed.SX
에서TX
으로 변환 하기 위해 가장 구체적인 변환 연산자가 호출 됩니다.The most specific conversion operator is invoked to convert fromSX
toTX
.TX
T
되지 않은 경우TX
에서T
로의 표준 암시적 변환이 수행 됩니다.IfTX
is notT
, then a standard implicit conversion fromTX
toT
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 typesS0
andT0
.S
또는T
nullable 형식이 면S0
및T0
은 해당 기본 형식입니다. 그렇지 않으면S0
와T0
각각S
및T
와 같습니다.IfS
orT
are nullable types,S0
andT0
are their underlying types, otherwiseS0
andT0
are equal toS
andT
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 ofS0
(ifS0
is a class or struct), the base classes ofS0
(ifS0
is a class),T0
(ifT0
is a class or struct), and the base classes ofT0
(ifT0
is a class). U
해당 하는 사용자 정의 및 리프트 변환 연산자 집합을 찾습니다.Find the set of applicable user-defined and lifted conversion operators,U
. 이 집합은S
를 사용 하거나 포괄 하는 형식에서T
를 사용 하거나 소유 하는 형식으로 변환 하는D
의 클래스 또는 구조체에서 선언 된 사용자 정의 및 리프트 된 암시적 또는 명시적 변환 연산자로 구성 됩니다.This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs inD
that convert from a type encompassing or encompassed byS
to a type encompassing or encompassed byT
.U
비어 있으면 변환이 정의 되지 않으며 컴파일 타임 오류가 발생 합니다.IfU
is empty, the conversion is undefined and a compile-time error occurs.U
에서 연산자의 가장 구체적인 원본 유형SX
를 찾습니다.Find the most specific source type,SX
, of the operators inU
:U
의 연산자 중 하나가S
변환 되 면SX
S
됩니다.If any of the operators inU
convert fromS
, thenSX
isS
.S
을 포함 하는 형식에서U
의 연산자가 변환 되 면 이러한 연산자의 결합 된 원본 형식 집합에서 가장 많이 포함 된 형식이SX
됩니다.Otherwise, if any of the operators inU
convert from types that encompassS
, thenSX
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.- 그렇지 않으면
U
연산자의 결합 된 원본 형식 집합에서 가장 많이SX
는 형식입니다.Otherwise,SX
is the most encompassing type in the combined set of source types of the operators inU
. 가장 많이 포괄 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
U
에서 연산자의 가장 구체적인 대상 유형TX
를 찾습니다.Find the most specific target type,TX
, of the operators inU
:U
연산자 중 하나가T
으로 변환 되 면TX
T
됩니다.If any of the operators inU
convert toT
, thenTX
isT
.- 그렇지 않고
U
의 연산자 중 하나가T
에 들어 있는 형식으로 변환 되는 경우 해당 연산자의 조합 된 대상 형식 집합에서 가장 많은 형식이TX
됩니다.Otherwise, if any of the operators inU
convert to types that are encompassed byT
, thenTX
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 inU
. 가장 일치 하는 형식을 찾을 수 없는 경우 변환이 모호 하 고 컴파일 타임 오류가 발생 합니다.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:
SX
에서TX
로 변환 하는 정확히 하나의 사용자 정의 변환 연산자가U
에 포함 된 경우이는 가장 구체적인 변환 연산자입니다.IfU
contains exactly one user-defined conversion operator that converts fromSX
toTX
, then this is the most specific conversion operator.- 그렇지 않고
SX
에서TX
로 변환 하는 리프트 변환 연산자가U
포함 되어 있으면 가장 구체적인 변환 연산자입니다.Otherwise, ifU
contains exactly one lifted conversion operator that converts fromSX
toTX
, 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
로의 표준 명시적 변환이 수행 됩니다.IfS
is notSX
, then a standard explicit conversion fromS
toSX
is performed.SX
에서TX
으로 변환 하기 위해 가장 구체적인 사용자 정의 변환 연산자가 호출 됩니다.The most specific user-defined conversion operator is invoked to convert fromSX
toTX
.TX
T
되지 않은 경우TX
에서T
로의 표준 명시적 변환이 수행 됩니다.IfTX
is notT
, then a standard explicit conversion fromTX
toT
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
에 동일한 수의 매개 변수가 있습니다.IfF
contains an anonymous_function_signature, thenD
andF
have the same number of parameters.F
에 anonymous_function_signature포함 되어 있지 않은 경우D
의 매개 변수가out
매개 변수 한정자를 포함 하지 않는 한D
에는 임의의 형식의 매개 변수가 0 개 이상 있을 수 있습니다.IfF
does not contain an anonymous_function_signature, thenD
may have zero or more parameters of any type, as long as no parameter ofD
has theout
parameter modifier.F
에 명시적으로 형식화 된 매개 변수 목록이 있으면D
의 각 매개 변수는F
의 해당 매개 변수와 동일한 형식 및 한정자를 가집니다.IfF
has an explicitly typed parameter list, each parameter inD
has the same type and modifiers as the corresponding parameter inF
.F
에 암시적으로 형식화 된 매개 변수 목록이 있으면D
에ref
또는out
매개 변수가 없습니다.IfF
has an implicitly typed parameter list,D
has noref
orout
parameters.F
본문이 식이 고D
에void
반환 형식이 있거나 비동기F
D
반환 형식이 있는 경우Task
의 각 매개 변수에F
의 해당 매개 변수 형식이 지정 되 면D
의 본문은F
(식 문)로 허용 되는 유효한 식 (wrt 식)입니다.If the body ofF
is an expression, and eitherD
has avoid
return type orF
is async andD
has the return typeTask
, then when each parameter ofF
is given the type of the corresponding parameter inD
, the body ofF
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 블록)입니다.If the body ofF
is a statement block, and eitherD
has avoid
return type orF
is async andD
has the return typeTask
, then when each parameter ofF
is given the type of the corresponding parameter inD
, the body ofF
is a valid statement block (wrt Blocks) in which noreturn
statement specifies an expression.F
의 본문이 식이 고F
D
이 비-비정적 반환T
형식을 포함 하는 경우, 또는F
이 비동기이 고D
에 반환 형식이 있는 경우Task<T>
의 각 매개 변수에F
의 해당 매개 변수 형식이 지정 되 면D
의 본문은 암시적으로F
로 변환할 수 있는 유효한 식 (wrt Expressions)입니다.If the body ofF
is an expression, and eitherF
is non-async andD
has a non-void return typeT
, orF
is async andD
has a return typeTask<T>
, then when each parameter ofF
is given the type of the corresponding parameter inD
, the body ofF
is a valid expression (wrt Expressions) that is implicitly convertible toT
.F
의 본문이 문 블록인 경우F
중 하나가 비동기가 아니고D
에 void가 아닌 반환 형식이 있는 경우T
또는F
비동기이 고D
에 반환 형식이Task<T>
있는 경우F
의 각 매개 변수에D
에서 해당 하는 매개 변수의 형식이 지정 되 면F
의 본문은 각return
문이T
으로 암시적으로 변환할 수 있는 식을 지정 하는 연결할 수 없는 끝점이 있는 유효한 문 블록 (wrt 블록)입니다.If the body ofF
is a statement block, and eitherF
is non-async andD
has a non-void return typeT
, orF
is async andD
has a return typeTask<T>
, then when each parameter ofF
is given the type of the corresponding parameter inD
, the body ofF
is a valid statement block (wrt Blocks) with a non-reachable end point in which eachreturn
statement specifies an expression that is implicitly convertible toT
.
간단 하 게 하기 위해이 섹션에서는 작업 형식 Task
및 Task<T>
(비동기 함수)에 대해 약식 형식을 사용 합니다.For the purpose of brevity, this section uses the short form for the task types Task
and Task<T>
(Async functions).
F
대리자 D
형식과 호환 되는 경우 람다 식 F
식 트리 형식 Expression<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
다음 예제에서는 A
형식의 인수를 사용 하 고 R
형식의 값을 반환 하는 함수를 나타내는 제네릭 대리자 형식 Func<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.
x
int
형식이 지정 된 경우 x+1
은 암시적으로 int
형식으로 변환할 수 있는 유효한 식이 기 때문에 첫 번째 할당은 익명 함수를 대리자 형식 Func<int,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
.
마찬가지로 x+1
(int
형식)의 결과가 double
형식으로 암시적으로 변환 되기 때문에 두 번째 할당에서는 익명 함수를 Func<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
제공 될 때 double
형식의 x+1
결과를 암시적으로 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
.
네 번째 할당은 x+1
(int
형식)의 결과를 작업 형식 Task<int>
의 결과 형식 int
로 암시적으로 변환할 수 있기 때문에 익명 비동기 함수를 Func<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. 대리자 형식 D
및 메서드 그룹으로 분류 되는 식 E
를 사용 하는 경우에는 다음에 설명 된 대로 E
의 매개 변수 형식 및 한정자를 사용 하 여 생성 된 인수 목록에 대 한 표준 형식 (적용 가능한 함수 멤버)이 하나 이상 포함 D
에 암시적 D
E
변환이 있습니다.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.
메서드 그룹에서 대리자 형식으로 변환 하는 컴파일 타임 응용 프로그램은 다음에 설명 되어 D
E
.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.
- 다음 사항을 수정 하 여 폼
E(A)
의 메서드 호출 (메서드호출)에 해당 하M
단일 메서드를 선택할 수 있습니다.A single methodM
is selected corresponding to a method invocation (Method invocations) of the formE(A)
, with the following modifications:- 인수 목록
A
은 각각 변수로 분류 되 고D
formal_parameter_list 에 해당 하는 매개 변수의 형식 및 한정자 (ref
또는out
)를 사용 하는 식의 목록입니다.The argument listA
is a list of expressions, each classified as a variable and with the type and modifier (ref
orout
) of the corresponding parameter in the formal_parameter_list ofD
. - 일반 형식 (적용 가능한 함수 멤버)에 적용할 수 있는 메서드 (확장 된 형식에만 적용 되는 것이 아님)만 고려 되는 후보 메서드입니다.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. 이렇게 하지 않으면 알고리즘은
D
와 동일한 수의 매개 변수를 갖는M
한 가지 최상의 방법을 생성 하며 변환이 있는 것으로 간주 됩니다.Otherwise the algorithm produces a single best methodM
having the same number of parameters asD
and the conversion is considered to exist. - 선택한 메서드
M
대리자 형식D
와 호환 (대리자 호환성) 되어야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생 합니다.The selected methodM
must be compatible (Delegate compatibility) with the delegate typeD
, or otherwise, a compile-time error occurs. - 선택한 메서드
M
인스턴스 메서드인 경우E
와 연결 된 인스턴스 식에서 대리자의 대상 개체를 결정 합니다.If the selected methodM
is an instance method, the instance expression associated withE
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 typeD
, 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 ofE(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 withE
:- 인스턴스 식이 계산 됩니다.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 isnull
, aSystem.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 isnull
. D
대리자 형식의 새 인스턴스가 할당 됩니다.A new instance of the delegate typeD
is allocated. 새 인스턴스를 할당 하는 데 사용할 수 있는 메모리가 부족 한 경우에는System.OutOfMemoryException
발생 하며 추가 단계가 실행 되지 않습니다.If there is not enough memory available to allocate the new instance, aSystem.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.