混合使用扩展方法、泛型和lambda表达式

本文关键字:泛型 lambda 表达式 方法 扩展 混合 | 更新日期: 2023-09-27 18:27:06

我正在将Haskell的/LiveScript each函数移植到C#,遇到了一些问题。这个函数的签名是(a → Undefined) → [a] → [a],我可以很好地处理Haskell或LS中的类型和lambda表达式,但C#让我感到困惑。这种扩展方法的最终用途应该是:

String[] str = { "Haskell", "Scheme", "Perl", "Clojure", "LiveScript", "Erlang" };
str.Each((x) => Console.WriteLine(x));

这样,我的输出应该是:

Haskell
Scheme
Perl
Clojure
LiveScript
Erlang

我目前自己对each的实现是:

public static void Each<T>(this IEnumerable<T> list, Action closure)
{
  foreach (var result in list)
  {
    Delegate d = closure;
    object[] parameters = { result };
    d.DynamicInvoke(parameters);
  }
}

问题是,在这里,我无法在lambda表达式中传递参数。我不会做(x) => ...

如何将参数传递给lambda表达式?在Haskell中使用第一类函数比在C#中更容易。我只是很困惑。

对于那些不知道Each实现的人来说,它用于副作用,返回自己的列表,并应用闭包迭代并将列表的每个值作为参数传递。它在PHP中的实现应该是:

public static function each($func) {
  // where $this->value is a list
  foreach ($this->value as $xs) {
    $func($xs);
  }
  return $this->value;
  // Or return $this; in case of method-chaining
}

有人能帮我吗?我搜索了一下,但不清楚。[我不希望使用Linq]

混合使用扩展方法、泛型和lambda表达式

您需要Action<T>而不是Action。您也可以直接调用它,而不是使用DynamicInvoke:

public static void Each<T>(this IEnumerable<T> list, Action<T> a)
{
  foreach (var result in list)
  {
    a(result);
  }
}