c# - lambda 作为默认参数

标签 c#

我正在寻找问题的答案 Get next N elements from enumerable没有找到任何令人满意的并酿造了我自己的。我想到的是

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

不过,我真正想要的是让 action 的默认值为 t=>t ,但我不知道如何使它成为默认参数。签名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++

作为旁注,我知道它在语法上没有任何区别,但如果我切换 T 会更容易阅读吗?和 R

最佳答案

默认值必须是常量,委托(delegate)的唯一常量值是 null引用。

我建议您改用重载。注意 t => t无论如何都无效,除非您知道有一个来自 IEnumerable<R> 的转换至 T ,我在任何地方都看不到。

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

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

...但那有点滥用它,您将无法判断 null 是否是实际上 来自认为他们正在传递非空值的调用者,并且希望您提出 ArgumentNullException .

编辑:此外,请注意您的方法存在根本性问题 - 迭代 block 将多次评估原始序列(每个 block 一次)以跳过正确的数量。最好编写一个方法,在返回之前急切读取每个 block 。我们在 MoreLINQ 中有类似的方法, 称为 Batch .注意 Batch正好有这里提到的过载 - 在这种情况下,t => t有效,因为重载的类型参数较少,所以我们知道身份转换没问题。

关于c# - lambda 作为默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11140348/

相关文章:

c# - 当锁没有竞争时, lock(...) 的开销是多少?

c# - 常规字符串和逐字字符串有什么区别?

c# - 通过反射获取 String.Trim 的 MethodInfo?

c# - 广播 Windows HWND_BROADCAST 消息

c# - 如何检查 StreamReader 是否仍然打开?

c# - 从字符串中获取特定字符后的字符

c# - 通知 ajax 调用 session 已超时或用户需要重新验证

c# - 从 C# 调用 python 代码(.py 文件)

c# - 如何使用 WMI 在 Hyper-V guest 上枚举网络适配器?

c# - 使用反射获取嵌套类型的容器类型