lambda as default argument

前端 未结 2 1895
既然无缘
既然无缘 2020-12-20 22:46

I was looking for an anwer to question Get next N elements from enumerable didn\'t find any satisfying and brewed my own. What I came up with was

IEnumerable         


        
相关标签:
2条回答
  • 2020-12-20 23:07

    It's the same for C#: create an overload.

    IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n){
        return Chunk<T, R>(src, n, t => t);
    }
    
    0 讨论(0)
  • 2020-12-20 23:13

    Default values have to be constants, and the only constant value for a delegate is a null reference.

    I suggest you use overloading instead. Note that t => t wouldn't be valid anyway, unless you know that there's a conversion from IEnumerable<R> to T, which I don't see anywhere.

    Aside from the lambda expression validity problem, you could use the null coalescing operator:

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

    ... but that would be sort of abusing it, and you wouldn't be able to tell whether the null was actually from a caller who thought they were passing a non-null value, and would prefer you to raise an ArgumentNullException.

    EDIT: Additionally, note that your method is fundamentally problematic - iterating over the chunks will evaluate the original sequence several times (once per chunk) in order to skip the right amount. It would probably be better to write a method which eagerly read each chunk before returning it. We have a similar method in MoreLINQ, called Batch. Note that Batch has exactly the overload mentioned here - and in this case, the t => t works, because the overload has fewer type parameters, so we know the identity conversion is okay.

    0 讨论(0)
提交回复
热议问题