2010-01-08 6 views
2

IEumerable 인터페이스에서 List.ConvertAll과 같은 확장 메서드에 대한 흥미로운 필요성이 있습니다. 이것은 here 전에 다뤄졌으며 하나의 해결책을 찾았습니다 here. 그 해결책에 대해 싫어하는 것은 변환 된 객체를 보관하기 위해 List를 작성한 다음 반환하는 것입니다. 나는 그가 자신의 기사를 쓸 때 LINQ를 사용할 수없는 의심, 그래서 내 구현은 이것이다 :IEnumerable <T> .ConvertAll & DDD

public static class IEnumerableExtension 
{ 
    public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> collection, Func<T, TOutput> converter) 
    { 
     if (null == converter) 
      throw new ArgumentNullException("converter"); 

     return from item in collection 
       select converter(item); 
    } 
} 

내가 이것에 대해 더 좋아하는 것은 내가 어떤 TOutput 년대의 전체 목록을로드 할 필요없이 '즉석에서'변환입니다 아르. Converter에서 Func으로 대리자의 유형을 변경했습니다. 컴파일은 동일하지만 내 의도가 명확 해 졌다고 생각합니다. - 이것이 유일한 유형 변환이되는 것은 아닙니다.

내 질문에 리드 : 내 저장소 계층에서 나는 ID의 목록을 반환하는 쿼리가 많이 있습니다. ID는 엔티티입니다. 나는이 ID를 다양한 방식으로 엔티티에 '변환'한 여러 클래스를 사용했습니다. 이 확장 방법을 나는 다음과 같은 코드로 모든 것을 졸이다 수 있어요 다음 '변환기'정말 저장소의 찾기 별 ID 방법이다

IEnumerable<Part> GetBlueParts() 
{ 
    IEnumerable<int> keys = GetBluePartKeys(); 
    return keys.ConvertAll<Part>(PartRepository.Find); 
} 

. 필자의 경우 '변환기'는 잠재적으로 상당히 많은 작업을 수행하고 있습니다. 누구든지이 접근 방식에 문제가있는 것을 볼 수 있습니까?

답변

10

이 접근법에서 볼 수있는 주요 문제는 완전히 필요하지 않다는 것입니다.

ConvertAll 메서드는 표준 LINQ 연산자 인 Enumerable.Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)과 아무런 차이가 없습니다. 이미 프레임 워크에있는 것의 확장 메소드를 작성할 이유가 없습니다.

당신은 다만 할 수 있습니다

IEnumerable<Part> GetBlueParts() 
{ 
    IEnumerable<int> keys = GetBluePartKeys(); 
    return keys.Select<int,Part>(PartRepository.Find); 
} 

참고 : 당신의 방법은 PartRepository.Find은 INT에 작동하고, 일부만 인스턴스를 반환하지 않는 한, 컴파일 할뿐만 아니라 <int,Part> 필요합니다. 당신이를 피하려면, 당신은 아마 수행 할 수 있습니다

IEnumerable<Part> GetBlueParts() 
{ 
    IEnumerable<int> keys = GetBluePartKeys(); 
    return keys.Select(i => PartRepository.Find<Part>(i)); // I'm assuming that fits your "Find" syntax... 
} 
+0

+1 이것을 지적하기 위해 ... LINQ없이 여전히 고민하고있는 사람들을 위해 내 대답을 남겨주세요. –

+0

Oh my gawd - Reed 당신은 절대적으로 맞습니다. 쏴 - 모두를 신경 쓰지 마라! – n8wrl

1

가 왜 yield 키워드를 사용하지 (그리고 필요로 각 항목을 변환)?

public static class IEnumerableExtension 
{ 
    public static IEnumerable<TOutput> ConvertAll<T, TOutput> 
     (this IEnumerable<T> collection, Func<T, TOutput> converter) 
    { 
     if(null == converter) 
      throw new ArgumentNullException("converter"); 

     foreach(T item in collection) 
      yield return converter(item); 
    } 
} 
+1

기술적으로 이전에 수행 한 Select를 사용하는 LINQ를 사용하여 이와 비슷한 방식으로 결과를 스트리밍합니다. 수락 해, 당신의 버전 (약간)을 좋아한다, 그러나 기본적으로 Select() 방법이 내부적으로하는 일을하고있다. 귀하와 귀하의 원본 포스터는 필요에 따라 변환되어 결과물을 스트림합니다. –

관련 문제