的
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