ITEM 42 :: EFFECTIVE C#


안녕하세요, 42번째 시간입니다. 자주 보다보니 반가운 제네릭이 나왔습니다.


이번 챕터는 Ienumerable 데이터 소스와 Iqueryable 데이터 소스를 구분하라, 입니다. 이 두 개의 제네릭을 구분하는 이유는 LINQ식으로 변환할 때 각 제네릭 별로 내부 수행과정과 그 결과가 다르기 때문이라고 생각합니다만, 그게 맞을지는 시작해봐야 알 것 같네요.

설명

  1. 둘은 굉장히 비슷한 API 정의를 지녔고 대부분의 상황에서 서로를 대체하여 사용할 수 있으나, 매번 그런 것은 아니다. 또한 내부적으로 동작하는 방은 완전히 다르다.

  2. 또한 대부분의 경우 쿼리작업을 수행할 때 Ienumerable를 사용하는 것보다 Iqueryable 를 사용하는 편이 훨씬 효율적이기 때문에 이 둘의 차이점을 잘 알아야 한다.

  3. 서로의 장단점은 명확하다. Ienumerable을 사용하게 되면, 먼저 시스템 리소스를 포함한 데이터를 로컬로 불러야하며, Iqueryable에 비해 상대적으로 더 많은 데이터를 가져와야 한다. 이는 성능상의 단점이 된다. 장점은 코드로 구현할 수 있는 쿼리표현식이 Iqueryable에 비해 자유롭다는 것이다.

  4. 반대로 Iqueryable을 사용하게되면, 시스템 성능도 개선되며 가져와야 할 데이터의 양도 적다. 다만, Ienumerable에 비해 쿼리 표현식이 제한된다는 단점이 있다.

  5. 쉽게 말해서 Ienumerable은 람다식을 주로 사용하므로, 각 메서드를 분석하여 그 내용을 토대로 작업을 수행하기 때문에, 로컬로 데이터를 가져와야 하는 것이고, Iqueryable은 표현 트리식을 분석한 후 분석한 정보를 토대로 메서드 집합과 연산자를 이해하는 것이기 때문에 가볍지만, 디테일한 표현식을 작성하는데 제한이 되는 것이다.

  6. 따라서 해당하는 인터페이스를 구현할 때 Iqueryable을 지원하는지 Ienumerable을 지원하는지 잘 알아야 한다.

  7. 간혹 동일한 T 타입에 대해서 특정 메서드가 Iqueryable 과 Ienumerable을 지원해야하는 경우, 코드중복이 발생할 가능성이 높으므로 AsQueryable()을 사용하여 Ienumerable를 IQueryable로 변경하면 중복을 피할 수 있다.

결론

얼핏 보기에 두개의 인터페이스는 동일한 기능을 제공하는 것 처럼 보이나, 이 둘은 매우 다르며, 쿼리 표현식을 구현하는데 있어서 방법이 매우 상이하다. 따라서 데이터 원본이 어떤 인터페이스를 제공하느냐에 따라 올바르게 쿼리를 구성해야 한다. 또한 올바른 형식으로 변수를 선언해야만 제대로 작업을 수행할 수 있다!