ITEM 36 :: EFFECTIVE C#


안녕하세요, 36번째 시간입니다. 책의 반을 넘어서 이젠 14개밖에 안 남았네요.


이번 챕터는 쿼리 표현식과 메서드 호출 구문이 어떻게 대응되는지 이해하라, 입니다. LINQ는 기본적으로는 2개의 표현방식이 존재하는데, 이는 쿼리 표현식과 메서드 호출 구문입니다. 근데, 사실, 쿼리 표현식은 내부적으로 변환되어 메서드 호출 구문으로써 컴파일러가 읽어들이게 됩니다. 따라서, 어떤식으로 쿼리 표현식이 메서드 호출 구문으로 변환되는지 알고 있다면, 쿼리에 대해 기능을 개선할 수도 있고, 그 내부 메서드를 구현할 수도 있게 됩니다. 다만, 아직 필자에게는 지식으로의 개념밖에 느껴지지 않아서 조금 어려운 개념인데, 자꾸 사용하다보면 늘겠지요.

설명

  1. C# 컴파일러는 쿼리 언어로 작성된 쿼리 표현식을 메서드 호출 구문으로 변환해준다.

  2. 클래스 설계자 입장에서는 내부의 함수가 쿼리 표현식의 where 가 메서드 호출 구문에서의 함수 Where()로 불리는 것과 같은, 쿼리 표현식이 메서드 호출 구문으로 변환되는 과정에 대해 확실히 알 필요성이 있다. 이를 알아야 기존 라이브러리를 개선할 가능성이 있을 경우 올바르게 코드를 작성할 수 있기 때문이다.

  3. C# 컴파일러는 쿼리 표현식 패턴에 포함된 개별 메서드가 어떤 의미를 가지고 있는지 전혀 개의치 않는다. 즉, 어떠한 기능을 가지고 있는지는 보지않고, 구문상 오류가 있는지만 판단한다는 이야기이다. 즉, 이를 코딩할 때는 생각보다 신중하게 짤 필요성이 있다. 왜냐면 이 의미는 컴파일러가 그 오류성에 대해 판단하지 않는다는 의미와 동일하기 때문이다.

  4. 따라서 쿼리 표현식에 포함된 메서드를 구현해야 한다면 그 구조는 물론이고 역할의 측면에서도 일관성을 유지해야 한다.

  5. Where -> Select -> Orderby -> Group -> Join, SelectMany 순으로 쿼리표현식에서 메서드 호출 구문으로 변환된다.

  6. 다행스러운 점은 대부분의 경우 컴파일러가 올바르게 변환 작업을 수행한다는 사실을 믿고 작업을 수행하면 된다. (특히 Ienumerable를 구현하는 타입을 작성하는 경우)

  7. 결국, 사용자가 원하는 커스터마이징을 위해선 이러한 쿼리 표현식이 메서드 호출 구문으로 변환되는 과정이 확실히 알아야 되는 이유가 된다.

  8. 그 마저도 Ienumerabel를 사용하면 대부분의 타입이 문제없이 작동하게 할 수 있지만, 이마저도 특수한 타입을 쓰는경우에는 모든 쿼리식에 대하여 문제없이 작동할 수 있도록 개선해야 한다.