Lambdas(=>运算符)-它们是什么,以及如何使用它们?

MSDN将lambda表达式定义如下:
Lambda表达式是一个匿名函数,可以包含表达式和语句,并且可以用于创建委托或表达式树类型。
好的,那是什么意思? 这是有关C#中匿名方法的演变的很好的阅读

无论如何,匿名方法就是它的模样。 这是一种未命名的方法。 在某些情况下,它们可能非常有用,尤其是当您需要提供一种可能很短并且不需要可重用的方法时。

因此,一个常见的任务是:单击按钮时显示一个消息框。 我们大多数人都知道如何编写的旧代码:

public Form1()
{
    InitializeComponent();
    Button b1 = new Button() { Text = "Button" };
    this.Controls.Add(b1);
    b1.Click += new EventHandler(b1_Click);
} 
void b1_Click(object sender, EventArgs e)
{
    throw new NotImplementedException();
}
很容易,但是为什么我需要为一个按钮编写一个命名方法? 它占用空间,并且不需要重复用于其他任何事情。

因此,一种“更好”(在这种情况下,较短)的方法可能是这样的:

public Form1()
{
    InitializeComponent();
    Button b1 = new Button() { Text = "Button" };
    this.Controls.Add(b1);
    b1.Click += delegate(object sender, EventArgs e) { MessageBox.Show("Clicked"); };
}
但是还有更短的语法:
public Form1()
{
    InitializeComponent();
    Button b1 = new Button() { Text = "Button" };
    this.Controls.Add(b1);
    b1.Click += (sender, e) => MessageBox.Show("Clicked");
}
分解lambda的实际语法:

(arg1,arg2,

... argN )=> {statement1; 声明2; ... return statementN; };

括号部分包含参数名称。 您没有为这些参数提供类型; 它们将由预期代表的签名自动键入。

请注意,对于单个参数,括号是可选的,实际上经常被省略。 对于零个或多个,它们是必需的。

“ =>”实际上是一个运算符。 您可以将其读为“前往”。

{括号}部分是方法主体。 它包含标准语句。 他们可能会(也可能不会)(但经常会)使用参数。 前面的示例没有,本文后面的示例将没有。

请注意,对于单个语句,方括号是可选的,并且在此示例中通常被省略。 对于多个语句,它们是必需的。 这类似于ifs和loops。

lambda的返回类型是自动的,就像参数类型一样。 它由应该匹配的签名定义。 在前面的示例中,其返回类型为void。 在下面的示例中,我们将使用返回一个布尔值的lambda。 如果确实使用单个语句,并且委托的返回类型不是void,则将返回单个语句的结果。 如果确实使用多个语句和括号,则必须使用return关键字专门返回一个值。

因此,也许是一个(稍微)更实际的例子。 我们有一个未排序的整数列表,需要将其过滤为所有大于4的值。幸运的是,System.Linq库包含IEnumerables的扩展方法,其中之一恰好是

Where() 。 Where()需要一个Function作为参数。 不是函数调用 ,而是对函数本身的引用( 委托 )。 where()将在后台循环遍历调用IEnumerable的每个元素,将每个值传递给提供的函数引用,对于返回true的每个值,将其存储在新的IEnumerable中,当达到IEnumerable时返回呼叫者结束。
public Form1()
{
    InitializeComponent();
    int[] list = new int[] { 1, 3, 2, 7, 4, 9, 6, 8, 5 };
    int[] result1 = list.Where(IsGreaterThanFour).ToArray();
    int[] result2 = list.Where(delegate(int x) { return x > 4; }).ToArray();
    int[] result3 = list.Where(x => x > 4).ToArray();
} 
private bool IsGreaterThanFour(int x)
{
    return x > 4;
}
同样,我们看到了完成同一件事的三种方法。 每种方式都将方法引用传递给Where方法。 第一种使用命名方法,考虑到简短和缺乏重用相关代码的需求,该解决方案非常不吸引人。 第二个使用匿名方法,第三个使用lambda快捷方式语法。 纯娱乐

实际上,在LINQ中有第四种使用相同方法的方法:

int[] result4 = (from x in list
                 where x > 4
                 select x
                ).ToArray();
对于这个示例,这种语法似乎有些过分了。 但由于它与SQL相似且易于可视化解析,因此对于针对对象数据源的较大查询可能很有用。

在IEnumerables的Linq扩展方法中,您会发现lambda最多用,因为它们大多数都希望有函数引用。 一旦了解了语法的工作原理,它们就会变得更容易编写。

另一个简单的例子:

我们有一个字符串列表,还有一个自定义类(MyClass),其中包含一个字符串(Value)和一个int(Count)。 我们想从我们的List <string>创建一个新的List <MyClass>。

public class MyClass
{
    public string Value { get; set; }
    public int Count { get; set; }
} 
public Form1()
{
    InitializeComponent();
    List<string> list = new List<string>() { "first", "second", "a third string" };
    List<MyClass> result = list.Select(x => new MyClass { Value = x, Count = x.Length }).ToList();
}
此lambda将字符串作为参数,并返回MyClass。 Select()将遍历调用的IEnumerable,并将每个返回的值存储在另一个IEnumerable中,完成后它将返回该值。 我们编写的lambda从字符串创建一个新的MyClass并返回它创建的值,该值存储在IEnumerable中,并在Select的末尾返回。

今天就这些,希望对大家有所启发。 如果您有任何疑问,请告诉我。

PS:我有点忙于为VB.NET编写此版本。 如果有人想帮忙,请成为我的客人。

From: https://bytes.com/topic/c-sharp/insights/888337-lambdas-operator-what-they-how-do-i-use-them

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值