C# lambda 表达式作为函数参数

Posted

技术标签:

【中文标题】C# lambda 表达式作为函数参数【英文标题】:C# lambda expressions as function arguments 【发布时间】:2011-07-20 18:50:12 【问题描述】:

我最近一直忙于深入研究 lambda 表达式,并且有一些我一直想学习但似乎无法正面或反面的特定功能。

假设我的代码中有以下逻辑:

List<A> foo; // assuming this is populated
string[] bar = foo.Select<A,string>(x => x.StringProperty).ToArray<string>();

现在,我可能想将整个操作抽象为一个处理程序方法,以便我可以这样做:

string[] bar = MakeArray<A,string>(foo, x => x.StringProperty);
int[] foobar = MakeArray<A,int>(foo, x => x.IntegerProperty);

我将如何编写该方法的主体?我预计将签名声明为:

U[] MakeArray<T,U>( /* some lambda magic? */ ) where T : IEntity 

但我不知道如何指定我期望一个 lambda 表达式作为方法参数,以及它如何准确地转换为方法的主体。

谁能告诉我如何创建上面的MakeArray() 函数?我很确定,一旦我看到它是如何完成的,我就可以从那里拿起它。

编辑

正如 cmets 中所指出的,MakeArray() 需要引用 IEnumerable&lt;&gt;。更新以反映这一点。

【问题讨论】:

FWIW 泛型的隐含性质可以通过不必在每个语句中显式声明类型来为您的代码添加可读值,但这可能是主观的。以下语句等于你的第一个选择..string[] bar = foo.Select(x =&gt; x.StringProperty).ToArray(); 如果您发现自己在整个代码中都使用数组,您可能需要考虑将它们重构为IEnumerable&lt;T&gt;IList&lt;T&gt;。那么这一切都不是必需的。另外,MakeArray 不需要引用 foo 吗? @Quintin ~ 是的,我有点喜欢明确说明的泛型(如果适用),所以很清楚我要抽出什么。不过你是对的。 @BlueRaja ~ 不,数组只是为了说明。但是,我明白你的意思! 【参考方案1】:
public static U[] MakeArray<T, U>(this IEnumerable<T> @enum, Func<T, U> rule)

    return @enum.Select(rule).ToArray();

【讨论】:

+1 谢谢!我将使用这个答案来展示该方法中的 Func 参数是如何使用的。真的很有帮助。【参考方案2】:

试试下面的

U[] MakeArray<T,U>(Func<T, U> projection) where T : IEntity 
  ...

当传递 lambdas 作为参数时,您通常希望匹配的参数是一个委托。在大多数情况下,您应该只使用适当的 Action&lt;&gt;Func&lt;&gt; 值。前者用于 void 返回 lambda,后者用于返回值。

【讨论】:

【参考方案3】:

您正在寻找Action&lt;&gt;Func&lt;&gt;

【讨论】:

【参考方案4】:

您可以使用 Func 和 Action 类。查看 LINQ Where 函数的签名作为示例: http://msdn.microsoft.com/en-us/library/bb534803.aspx

【讨论】:

感谢您的链接!我一直想知道他们是如何实现所有这些魔法的。【参考方案5】:

你可以创建扩展

public static class MakeArrayExtension

    public static U[] MakeArray<T, U>(this IEnumerable<T> collection, Func<T,U> func)
    
        return collection.Select(func).ToArray();
    

然后像这样使用它

List<A> foo; // assuming this is populated
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty);

【讨论】:

以上是关于C# lambda 表达式作为函数参数的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将 lambda 函数作为命名参数传递

Kotlin标准库函数 ② ( run 标准库函数 | run 函数传入 Lambda 表达式作为参数 | run 函数传入函数引用作为参数 )

将Lambda表达式作为参数传递并解析-在构造函数参数列表中使用Lambda表达式

kotlin方法传入lambda表达式参数并调用invoke什么意思

Lambda表达式

Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )