ValueTuple 공 변형은 무엇입니까?


35

이것은 C # 7.3 (프레임 워크 4.8)에서 올바르게 컴파일됩니다.

(string, string) s = ("a", "b");
(object, string) o = s;

나는 이것이 다음에 대한 구문 설탕이며 올바르게 컴파일된다는 것을 알고 있습니다.

ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;

그래서, ValueTuples가 할당 될 수 있다는 것을 나타납니다 covariantly , 굉장하다 !

불행히도, 나는 왜 그런지 이해하지 못한다 . 나는 C #이 인터페이스와 델리게이트에 대한 공분산만을 지원 한다는 인상을 받았다 . ValueType둘 다 아닙니다.

사실,이 기능을 내 코드로 복제하려고하면 실패합니다.

struct MyValueTuple<A, B>
{
    public A Item1;
    public B Item2;

    public MyValueTuple(A item1, B item2)
    {
        Item1 = item1;
        Item2 = item2;
    }
}

...

MyValueTuple<string, string> s = new MyValueTuple<string, string>("a", "b");
MyValueTuple<object, string> o = s;
// ^ Cannot implicitly convert type 'MyValueTuple<string, string>' to 'MyValueTuple<object, string>'

그렇다면 왜 ValueTuples를 공변량으로 할당 MyValueTuple할 수는 없습니까?


2
이것은 당신이 할당하는 방법을 같은 컴파일러에 의한 가능성이 특별 대우 인 nullA를 Nullable<T>이 구조체 비록.
juharr

2
사실, 두 번째 과제에 대한 다음과 같은 코드의 모습을 디 컴파일 :ValueTuple<object, string> o = new ValueTuple<object, string>(s.Item1, s.Item2);
라세 V. 칼슨에게

2
튜플은 이상하고 기본 CLR 표현에 의존하는 대신 c # 컴파일러 프론트 엔드에서 완전히 구현됩니다. 그 할당 연산자는 당신이 생각하는 것을하지 않습니다.
Jeremy Lakeman

2
public static implicit operator MyValueTuple<A, B>(MyValueTuple<string, string> v) { throw new NotImplementedException(); }할당을 해체 하는 암시 적 연산자를 추가하십시오 . 또한, 좋은 질문입니다!
Çöđěxěŕ

1
@ Çöđěxěŕ 황소 눈! 컴파일 가능하게하고 예외는 예상대로 발생합니다.
Mong Zhu

답변:


25

실제로 여기서 일어나고있는 일은 파괴적인 임무라고 생각합니다. 튜플 할당은 암시 적 구성 요소를 변환하려고합니다, 할당 할 수 있습니다로 string하는 object, 즉 여기서 발생하는 것입니다.

이 언어는 동일한 수의 요소를 갖는 튜플 유형 간의 할당을 지원하며, 각 오른쪽 요소를 해당 왼쪽 요소로 암시 적으로 변환 할 수 있습니다. 다른 전환은 할당에 고려되지 않습니다.

출처

sharplab.io에서 참조하십시오


4
방금 SharpLab에서 시도해 보았으며 정확히 그렇게 합니다.
John

3
이를 강화하기 위해 OP의 원래 예제에서 s유형 을 변경 (string, object)하면 항목간에 암시 적 변환이 발생하고 문자열이 암시 적으로 문자열로 변환 될 수 있지만 그 반대의 경우는 변환 오류가 발생합니다.
Eric Lease
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.