11.5.2 익명 타입
익명 타입은 LINQ 기능의 일부로 소개되기도 했고, 경험적으로도 LINQ를 사용할 때 가장 많이 사용된다. 메서드 내에서 일반적인 변수를 사용하는 용도로 익명 타입을 사용할 수 없는 것은 아니지만, 제품 코드에서 사용한 예를 본 적은 없다.
익명 타입이 제공하는 훌륭한 기능의 대부분은 C# 7의 튜플에서도 제공된다. 튜플 요소를 명명할 수 있고, 동일성 비교를 간단히 수행할 수 있으며, 군더더기 없는 문자열 출력 기능을 활용할 수도 있다. 익명 타입의 주요 문제점은 역시 익명이라는 점이다. 이 때문에 메서드의 반환 타입으로 사용할 수도 없고, 타입 안정성을 유지한 채로 속성으로 사용할 수도 없다(기본적으로 object나 dynamic을 사용해야 한다. 타입 정보는 런타임에는 유지되지만 컴파일러는 그 정보를 알 수 없다). C# 7의 튜플은 이러한 문제가 없다. 앞서 살펴본 바와 같이 메서드의 반환 타입으로도 사용할 수 있다.
튜플과 비교했을 때 익명 타입이 가지는 장점은 아래 네 가지 정도를 꼽을 수 있겠다.
• C# 7.0에서 프로젝션 초기화자를 사용할 경우 하나의 구분자만으로도 이름과 값을 모두 지정할 수 있다. 이는 튜플에 비해 상대적으로 간단하다. new { p.Name, p.Age }와 (name: p.Name, age: p.Age)를 비교해 보자. 그런데 C# 7.1이 출시되면서 튜플 요소의 이름을 추론하는 기능이 추가되었으므로 이제는 (p.Name, p.Age)와 같이 사용할 수 있게 개선되었다.
• 익명 타입의 문자열 출력 결과 내에는 이름이 포함되어 있어서 진단 용도로는 좀 더 편리할 수 있다.
• 익명 타입은 외부 프로세스에서 수행되는 LINQ 제공자(데이터베이스로의 쿼리 등을 담당하는)와도 함께 사용할 수 있다. 반면 튜플 리터럴은 현재까지 표현식 트리에서 사용할 수 없기 때문에 이런 부분에서는 상당한 약점이 있다.
• 가끔은 익명 타입의 객체를 파이프라인을 통해 전달해야 할 때가 있는데, 하나의 참조만 전달하면 되므로 튜플에 비해 효율적이다. 대부분 이 정도를 문제로 여기지는 않으며, 더불어 튜플을 사용하면 가비지 수집기가 정리해야 하는 객체를 만들지 않아도 되므로 더 이득이라고 여기기도 한다.
특히 C# 7.1을 사용한다면 튜플 요소의 이름을 추론할 수 있기 때문에 LINQ to Object를 사용할 때 튜플을 광범위하게 사용할 수 있다.