2012-06-21 4 views
4

질문에 대한 답변을 찾고 있는데 Get next N elements from enumerable은 내 자신을 만족스럽고 양조하지 못했습니다. 내가 생각 해낸 것은 정말 생각처럼 작업이 t=>t의 기본을 가지고하는 것입니다 것입니다 무엇기본 인수로 람다

IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action){ 
    IEnumerable<R> head; 
    IEnumerable<R> tail = src; 
    while (tail.Any()) 
    { 
    head = tail.Take(n); 
    tail = tail.Skip(n); 
    yield return action(head); 
    } 
} 

했다, 그러나 나는 기본 인수 있는지 확인하는 방법을 알아낼 수 없습니다. IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action = t=>t) 시그니처에 구문 오류가 발생합니다.

내 질문은, 어떻게합니까?

나는이 Specifying a lambda function as default argument 동일하지만 C# 대신 보조 노트로

C++

의, 나는 그것이 어떤 구문 차이를하지 않습니다 알고 가정,하지만 난 TR을 전환 한 경우는 쉽게 읽을 수있을 것입니다 ?

+0

사이드 노트 : 예, 적어도 전환하고 TSource 및 TResult로 이름을 바꿀 수 있습니다. (기본 LINQ 방법과 일치 할 것 같아요.) – Rawling

답변

10

기본값은 상수 여야하며 대리인의 유일한 상수 값은 null입니다.

오버로드를 사용하는 것이 좋습니다. IEnumerable<R>에서 T으로의 변환이 있음을 알지 못한다면 아무래도 t => t이 유효하지 않습니다. 이외에도 람다 식의 유효성 문제에서

, 당신 널 병합 연산자 사용할 수 있습니다

IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, 
          Func<IEnumerable<R>, T> action = null) 
{ 
    action = action ?? (t => t); 
    ... 
} 

을 ...하지만 그게 학대 종류의 것, 당신은 말할 수 없을 것입니다 null이던지 실제로 null이 아닌 값을 전달한 것으로 생각되는 발신자가인지 여부를 확인하고 ArgumentNullException을 제기하는 것이 좋습니다.

편집 : 또한 메서드가 근본적으로 문제가 있음을 유의하십시오. 청크를 반복하면 올바른 양을 건너 뛰기 위해 원래 시퀀스를 여러 번 (청크마다 한 번) 평가합니다. 을 반환하기 전에 각 청크를 읽는 방법을 쓰는 것이 좋습니다. MoreLINQ에 비슷한 방법이 있습니다 (Batch). Batch에는 정확하게 여기에 언급 된 오버로드가 있으며이 경우에는 t => t이 작동합니다. 오버로드에 더 적은 유형 매개 변수가 있기 때문에 ID 변환이 괜찮음을 알 수 있습니다.

+0

t => t를 사용하는 http://pastebin.com/T3RDxg7x는 linqpad에서 예상대로 작동합니다 ('yield return action (head)'->'yield return head'). 내가 여기서 무엇을 놓치고 있니? – Martijn

+0

@Martijn : 귀하의 경우 * 호출 * 코드는 형식 인수 (IEnumerable 및 int)를 알고 있기 때문에 변환이 괜찮음을 알고 있습니다. 일반적인 방법은 그것을 모릅니다. –

+0

편집에 댓글 달기 : 나는'result = Skip (n)'이 O (결과의 크기)가 아닌 O (n)이되어서 컬렉션에 대해 두 번의 반복 만 허용한다고 덧붙였다. 그것이 한 번 이상 반복 될 수있는 컬렉션이라고 가정합니다. MoreLINQ가 수행하는 버킷 사용은 아마도 더 현명한 아이디어 일 것입니다. – Martijn

2

C#의 경우와 동일합니다. 오버로드를 만듭니다.

IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n){ 
    return Chunk<T, R>(src, n, t => t); 
} 
관련 문제