다음을 통해 공유


Target-Typed 조건식

메모

이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.

기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 그러한 차이점은 언어 디자인 모임(LDM) 관련노트에 기록되어 있습니다.

사양문서에서 C# 언어 표준에 기능 스펙렛을 채택하는 프로세스에 대해 자세히 알아볼 수 있습니다.

조건식 변환

조건식 c ? e1 : e2일 때

  1. e1e2에 공통 유형이 없거나
  2. 공통 형식이 있지만 e1 또는 e2 식 중 하나에 해당 형식으로의 암시적 변환이 없는 경우

조건식에서 e1Te2T변환이 있는 모든 형식 T 암시적 변환을 허용하는 새로운 암시적 조건식 변환 정의합니다. 조건식이 e1e2 간의 공통 형식이 없고 조건식 변환에도 해당되지 않으면 오류입니다.

표현식에서 더 나은 변환

우리는 바꾼다

표현에서 더 나은 변환

E을 형식 T1로 변환하는 암시적 변환 C1가 있고, 식 E를 형식 T2로 변환하는 암시적 변환 C2가 주어졌을 때, ET2과 정확히 일치하지 않고 다음 조건 중 하나 이상을 만족할 경우, C1C2보다 더 나은 변환입니다.

  • ET1과 정확히 일치합니다 (§12.6.4.5)
  • T1 T2(§12.6.4.7)보다 더 나은 변환 대상입니다.

표현식에서 더 나은 변환

암시적 변환 C1가 식 E을 형식 T1로 변환하고, 암시적 변환 C2가 식 E를 형식 T2로 변환하는 경우, 만약 ET2과 정확히 일치하지 않으며 다음 조건 중 하나 이상을 만족한다면, C1C2보다 더 나은 변환입니다.

  • E 정확히 일치하는 T1 (§12.6.4.5)
  • C1 조건식 변환 아니며 C2조건식 변환.
  • (§12.6.4.7) 보다 더 나은 변환 대상이며 모두 조건식 변환을 조건식 변환아닙니다.

캐스트 식

현재 C# 언어 사양은

T 형식Eunary_expression형식인 (T)E양식의 cast_expression 형식 TE 값의 명시적 변환(§10.3)을 수행합니다.

조건식 변환이 있는 경우ET변환할 수 있습니다. 조건식 변환을 추가하면서 우리는 다른 모든 변환을 조건식 변환보다 선호하며, 조건식 변환는 최후의 수단으로만 사용합니다.

디자인 노트

으로의 변경 이유는 식로부터 더 나은 변환을 위해서이며, 이는 다음과 같은 경우를 처리하기 위한 것입니다.

M(b ? 1 : 2);

void M(short);
void M(long);

이 방법에는 두 가지 작은 단점이 있습니다. 첫째, 스위치 식과 완전히 같지는 않습니다.

M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)

이는 여전히 호환성을 깨뜨리는 변경이지만, 그 범위가 실제 프로그램에 미치는 영향은 적을 것입니다.

M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.

M(short, short);
M(long, long);

long로의 변환이 첫 번째 인수에는 더 적합합니다(이는 조건식 변환를 사용하지 않기 때문입니다). 그러나 두 번째 인수의 경우 short로의 변환이 더 나은 선택입니다(이는 shortlong과 비교하여 더 나은 변환 대상이기 때문입니다). 이 때문에 모호함이 발생합니다. 이 호환성이 손상되는 변경은 기존 프로그램의 동작을 자동으로 변경하지 않기 때문에 덜 심각해 보입니다.

캐스트 식에 대한 메모의 이유는 다음과 같은 경우를 처리하기 위한 것입니다.

_ = (short)(b ? 1 : 2);

이 프로그램은 현재 intshort명시적 변환을 사용하며 이 프로그램의 현재 언어 의미를 유지하려고 합니다. 변경 내용은 런타임에서 관찰되지 않지만, 다음 프로그램을 사용하면 변경 내용이 관찰될 수 있습니다.

_ = (A)(b ? c : d);

여기서 cC형식이고, dD형식이며, CD암시적 사용자 정의 변환, DA암시적 사용자 정의 변환, CA암시적 사용자 정의 변환이 있습니다. 이 코드가 C# 9.0 이전에 컴파일된 경우, b가 true일 때 우리는 c에서 D로, 그리고 그다음에 A로 변환됩니다. 조건식 변환을 사용할 경우, b가 true일 때 c에서 A로 직접 변환하여, 다른 사용자 코드 시퀀스를 실행합니다. 따라서 기존 동작을 유지하기 위해 조건식 변환 캐스트의 최후의 수단으로 처리합니다.