lambda作为默认参数

Mar*_*ijn 5 c#

我正在寻找一个问题的答案从枚举得到下一个N元素没有找到任何令人满意和酿造我自己.我想出的是

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

我真的想要的是让动作有默认值t=>t,但我无法弄清楚如何使它成为默认参数.签名IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action = t=>t)给出了语法错误.

我的问题是,我该怎么做?

我认为这与将lambda函数指定为默认参数但与C#而不是C++相同

作为一个方面说明,我知道这不作任何语法差别,但它会更容易阅读,如果我切换TR

Jon*_*eet 12

默认值必须是常量,委托的唯一常量值是null引用.

我建议你改用重载.请注意,t => t无论如何都不会有效,除非您知道转换IEnumerable<R>T,我在任何地方都看不到.

除了lambda表达式有效性问题,您可以使用null合并运算符:

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

......但是这将是有点滥用它,你将无法告知是否null真正从谁想到他们传递一个非空值,并希望你提出一个呼叫者ArgumentNullException.

编辑:此外,请注意您的方法从根本上是有问题的 - 迭代块将多次评估原始序列(每个块一次),以跳过正确的数量.编写一个在返回之前急切阅读每个块的方法可能会更好.我们在MoreLINQ中有一个类似的方法,叫做Batch.注意,Batch这里提到了完全超载 - 在这种情况下,t => t工作,因为重载具有较少的类型参数,所以我们知道身份转换是可以的.