더북(TheBook)

예제 11-10의 출력 결과를 보면 대소문자를 구분하지 않는 방식으로 비교 연산이 수행되었음을 알 수 있다.

(A, b) and (a, B) - comparison: 0; equal: True
(a, B) and (a, a) - comparison: 1; equal: False
(a, B) and (b, a) - comparison: -1; equal: False

이런 종류의 비교 연산이 주는 이득은 모두 조합 가능성과 연관되어 있다. 비교기는 튜플 내의 개별 요소들을 비교하는 방법을 구현하고 있으므로 튜플은 개별 요소를 비교할 때 이 비교기에 작업을 위임하면 된다. 이는 LINQ와도 다소 유사한데, 컬렉션 내의 개별 요소에 대한 연산을 지정함으로써 컬렉션 전반에 걸쳐 해당 작업을 수행한다는 측면이 특히 그렇다.

하지만 이는 튜플이 튜플 요소로서 동일한 타입을 사용한다는 가정하에서만 올바르게 동작한다. 만약 (string, int, double)과 같이 튜플 요소들이 서로 상이한 타입을 가질 때도 구조적 비교를 수행해야 한다면, 비교기가 string, int, double 타입 각각을 비교할 수 있도록 코드를 작성해야 한다. 물론 이 경우에도 피연산자의 타입이 동일한 경우에만 비교를 수행한다. ValueTuple의 구현체는 대응되는 튜플 요소의 타입이 같은 경우에만 비교를 허용한다. 예를 들어 (string, int)(int, string)을 비교하면 튜플 요소를 비교하기도 전에 예외가 발생할 것이다. 비교기의 구현 예는 이 책의 범위를 넘어선다. 하지만 샘플 코드에는 CompoundEqualityComparer라는 구현 예를 포함했으므로 유사한 코드를 작성할 때 참고하자.

지금까지 알아본 내용은 ValueTuple<…>에서 애리티가 2부터 7까지인 타입에 대한 내용이다. 11.4.1절에서 언급한 바와 같이 이제 나머지 세 유형의 ValueTuple에 대해서 살펴볼 차례다. 우선 뜻밖에도 가장 관련이 깊은 ValueTuple<T1>ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>를 함께 살펴보자.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.