더북(TheBook)

메타데이터 내의 튜플 요소 이름

이번 장에서 여러 번 살펴봤던 MinMax 메서드로 다시 돌아가 보자. LINQ to Object를 보강하기 위해 조합에 사용 가능한 public 메서드를 패키지화해서 노출한다고 해보자. 튜플 요소에 명명한 이름을 사용할 수 없다면 가독성이 상당히 나빠질 것이다. 그런데 CLR 수준에서는 반환값으로 튜플을 반환하면 튜플 요소의 이름을 유지하지 못한다고 하지 않았던가. 다행히 CLR은 out 매개변수와 매개변수의 기본값을 지정할 때 사용했던 메커니즘을 준용해서 CLR 차원에서 지원하지 않는 기능을 보강해 준다. 바로 특성을 이용하는 것이다!

이 경우 컴파일러는 TupleElementNamesAttribute라는 특성을 이용하여 해당 어셈블리 내에 튜플 요소의 이름을 인코딩해 둔다(유사한 성격의 다른 특성들과 마찬가지로 이 특성은 System.Runtime.CompilerServices 네임스페이스에 정의되어 있다). 예를 들어 public MinMax 메서드의 선언부를 C# 6로 나타내면 다음과 같다.

[return: TupleElementNames(new[] {"min", "max"})]
public static ValueTuple<int, int> MinMax(IEnumerable<int> numbers)

C# 7 컴파일러로 이 코드를 컴파일하면 튜플 문법을 직접 사용하라고 오류 메시지를 출력할 것이다. 하지만 이 코드를 C# 6로 컴파일하면 C# 7에서 튜플 요소에 이름을 부여한 것과 동일한 내용을 어셈블리에 추가해 준다.

중첩 타입을 사용하는 경우에는 이 특성이 다소 복잡하게 사용되지만, 특성에 직접 접근하여 그 내용을 해석해야 할 일은 거의 없을 것 같다. 단지 이처럼 특성을 이용하여 튜플이 지역 변수 수준을 벗어날 때 튜플 요소에 부여된 이름을 사용할 수 있도록 해준다는 사실을 아는 것만으로도 충분히 가치가 있다고 생각한다. 멤버가 private으로 선언된 경우에도 C# 컴파일러는 동일한 특성을 생성해 주는데, 사실 이 경우에는 이러한 특성이 없어도 올바르게 동작한다. 이는 접근 제한자를 고려하지 않고 멤버들을 동일한 방식으로 처리하도록 하여 논리를 단순하게 유지하기 위한 것으로 생각된다.

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