튜플 타입의 ID 변환
ID 변환의 개념은 C#의 첫 번째 버전부터 존재하던 개념이었으며, 그간 여러 번에 걸쳐 그 내용이 확장되어 왔다. C# 7 이전에는 다음 규칙에 따라 동작했다.
• 모든 타입은 자신과 동일한 타입으로 ID 변환이 가능하다.
• object와 dynamic 사이에는 ID 변환이 가능하다.
• 요소 타입 간에 ID 변환이 가능하다면 해당 배열에 대해서도 ID 변환이 가능하다. 예를 들어 object[]와 dynamic[] 간에는 ID 변환이 가능하다.
• 제네릭 타입은 타입 인수 간 변환이 가능하면 구체화된 제네릭 타입(constructed generic type) 간에도 ID 변환이 가능하도록 확장된다. 예를 들어 List<object>와 List<dynamic> 간에는 ID 변환이 가능하다.
튜플은 이외에 다른 종류의 ID 변환을 지원하는데, 튜플 내의 각 요소별로 ID 변환이 가능하고 애리티가 같다면 요소의 이름과 무관하게 ID 변환이 가능하다. 구체적인 예를 들자면, 다음 세 개의 튜플 타입은 모두 양방향으로(ID 변환은 항상 대칭적) ID 변환이 가능하다.
• (int x, object y)
• (int a, dynamic d)
• (int, object)
이러한 방식은 구체화된 제네릭 타입에 대해서도 동일하게 적용된다. 그리고 튜플 요소 타입 또한 구체화된 제네릭 타입이 될 수 있다. 구체적인 예로 다음 두 타입은 상호 간 ID 변환이 가능하다.
• Dictionary<string, (int, List<object>)>
• Dictionary<string, (int index, List<dynamic> values)>
튜플 타입과 구체화된 제네릭 타입을 함께 사용할 때는 ID 변환이 꽤나 중요하다. (int, int)를 (int x, int y)로 변환하는 것은 쉽지만, IEnumerable<(int, int)>를 IEnumerable<(int x, int y)>로 변환하거나 혹은 그 반대 방향으로 변환하는 것이 불가능하다면 상당히 불편할 것이다.