拉姆达为默认参数 [英] lambda as default argument

查看:120
本文介绍了拉姆达为默认参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一个前面回答质疑获取下一个n个元素枚举没有发现任何满足和酿造我自己的。我想出了

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<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);
  }
}



我真的想虽然是有动作有 T =>的默认;吨,但我无法弄清楚如何使之成为默认参数。签名的IEnumerable< T>大块< T,R>(IEnumerable的< R> SRC,诠释N,Func键< IEnumerable的< R>中T>行动= T => T)给出了一个语法错误

What I would really like though, is to have action have a default of t=>t, but I can't figure out how to make that a default argument. The signature IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action = t=>t) gives a syntax error.

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

My question is, how do I do this?

我想这是相同的Specifying~~V lambda函数作为默认参数但对于C#,而不是C ++

I suppose this is identical to Specifying a lambda function as default argument but for C# instead of C++

作为一个方面说明,我知道这不作任何语法差别,但它会读如果我切换更容易 T 和<$ C $ ç>研究?

As a side note, I know it doesn't make any syntactical difference, but would it be easier to read if I switched T and R?

推荐答案

默认值必须是常量,而对于委托唯一不变的值是引用。

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

我建议你使用重载来代替。需要注意的是 T => ŧ将是无效的,无论如何,除非你知道,有一个从的IEnumerable℃的转换; R> T ,我没有看到任何地方。

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.

除了lambda表达式的有效性问题,你的 的可以使用空合并运营商:

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);
    ...
}



...但是这将是排序滥用它,你将无法告诉是否是的实际的从谁想到他们传递一个非空值呼叫者,并希望你提出的 ArgumentNullException

... 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.

编辑:此外,注意你的方法是根本问题 - 遍历块将为了跳过适量评价原始序列几次(一旦每块)。它可能会更好写一个热切的返回之前读取每个块的方法。我们在 MoreLINQ 类似的方法,叫做的 批量 。需要注意的是批量已经完全超负荷这里所说的 - 在这种情况下, T => ŧ的作品,因为过载较少类型参数,所以我们知道身份的转换是好的。

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.

这篇关于拉姆达为默认参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆