阅读this article之后,我无法弄清楚为什么使用lambda表达式。公平地说,我认为我没有正确理解委托和表达式树类型是什么,但我不明白为什么有人会使用lambda表达式而不是声明的函数。有人可以开导我吗?
答案 0 :(得分:60)
首先:简洁和地方性:
您更愿意写作,阅读和维护?这样:
var addresses = customers.Select(customer=>customer.Address);
或:
static private Address GetAddress(Customer customer)
{
return customer.Address;
}
... a thousand lines later ...
var addresses = customers.Select(GetAddress);
如果只需将您需要的代码放在需要的地方作为简短表达式,那么将程序与成百上千的四行函数混为一谈有什么意义呢?
第二: lambdas关闭本地范围
您更愿意阅读,编写和维护这一点:
var currentCity = GetCurrentCity();
var addresses = customers.Where(c=>c.City == currentCity).Select(c=>c.Address);
或:
static private Address GetAddress(Customer customer)
{
return customer.Address;
}
private class CityGetter
{
public string currentCity;
public bool DoesCityMatch(Customer customer)
{
return customer.City == this.currentCity;
}
}
....
var currentCityGetter = new CityGetter();
currentCityGetter.currentCity = GetCurrentCity();
var addresses = customers.Where(currentCityGetter.DoesCityMatch).Select(GetAddress);
当您使用lambda时,所有令人烦恼的代码都是为您编写的。
第三:查询理解被重写为lambdas
当你写:
var addresses = from customer in customers
where customer.City == currentCity
select customer.Address;
它会被转换为lambda语法。许多人发现这种语法很难阅读,但我们需要lambda语法才能真正使用它。
第四: lambdas可选择类型推断
请注意,我们不必在上面的查询理解中或lambda版本中给出“customer”类型,但在将其声明为静态方法时,我们必须给出形式参数的类型。编译器很聪明地从上下文推断lambda参数的类型。这使您的代码更少冗余,更清晰。
第五: Lambdas可以成为表达树
假设您要求网络服务器“向我发送当前城市中客户的地址”。您是否希望(1)从网站上下载一百万客户并在客户端计算机上进行过滤,或者(2)向网站发送一个对象,告诉它“查询包含当前城市的过滤器,然后选择地址“?让服务器完成工作并仅向您发送匹配的结果。
表达式树允许编译器将lambda转换为可在运行时转换为另一种查询格式并发送到服务器进行处理的代码。在客户端上运行的小助手方法不会。
答案 1 :(得分:5)
在声明函数中使用lambda的主要原因是需要在委托表达式中使用一段本地信息。例如
void Method(IEnumerable<Student> students, int age) {
var filtered = students.Where(s => s.Age == age);
...
}
Lambdas允许轻松捕获在委托表达式中使用的本地状态。手动执行此操作需要大量工作,因为您需要声明函数和包含类型以保持状态。例如,上面没有lambda
void Method(IEnumerable<Student> students, int age) {
var c = new Closure() { Age = age };
var filtered = students.Where(c.WhereDelegate);
...
}
class Closure {
public int age;
bool WhereDelegate(Student s) {
return s.Age == age;
}
}
输入此内容很繁琐且容易出错。 Lambda表达式自动执行此过程。
答案 2 :(得分:4)
让我们暂时将表达式树排除在等式之外,并假装lambdas只是写代表的一种较短的方式。
这仍然是C#等静态类型语言领域的一大胜利,因为这些语言需要编写大量代码才能实现相对简单的目标。你需要比较字符串长度的字符串数组吗?你需要为此编写一个方法。你需要写一个类来放入方法。然后好的做法要求这个类应该在它自己的源文件中。除了最小的项目之外,所有这些都会增加。当我们谈论小事时,大多数人都想要一个不那么冗长的目标路径,而lambdas就像它能够得到的那样简洁。
此外,lambdas可以轻松创建闭包(从当前作用域捕获变量并延长其生命周期)。这不是魔术(编译器通过创建一个隐藏类并执行一些你可以自己做的其他转换来实现),但它比手动替代方法更方便。
然后是表达式树:一种编写代码的方法,让编译器将此代码转换为可在运行时解析,修改甚至编译的数据结构。这是一个非常强大的功能,打开了令人印象深刻的功能的大门(我绝对认为LINQ是)。你可以“免费”获得它。
答案 3 :(得分:3)
http://msdn.microsoft.com/en-us/magazine/cc163362.aspx
关于lambda是什么的好文章,以及为什么你可以/应该使用它们。
基本上,lambda表达式 提供编译器的简写 发出方法并将它们分配给 代表;这一切都是为你完成的。 lambda带来的好处 你没有得到的表达 委托/功能组合就是这样 编译器执行自动类型 推断lambda参数
答案 4 :(得分:1)
他们大量使用LINQ,实际上如果没有它,LINQ会非常糟糕。你可以这样做:
Database.Table.Where(t =&gt; t.Field == “你好”);
答案 5 :(得分:0)
它们可以轻松地将一个简单的功能传递给另一个功能。例如,我可能想对列表中的每个项目执行任意的小函数(也许我想对它进行平方,或者取平方根,或者等等)。我可以编写一次,然后将我后面定义的任意功能应用于每个项目,而不是为每种情况编写新的循环和函数。
答案 6 :(得分:0)
Lambda让代码变得简短而又甜蜜。请考虑以下两个示例:
公共班学生
{
public string Name { get; set; }
public float grade { get; set; }
public static void failed(List<Student> studentList, isFaild fail)
{
foreach (Student student in studentList)
{
if(fail(student))
{
Console.WriteLine("Sorry" + " "+student.Name + " "+ "you faild this exam!");
}
}
}
public delegate bool isFaild(Student myStudent);
class Program
{
static void Main(string[] args)
{
List<Student> studentsList = new List<Student>();
studentsList .Add(new Student { ID = 101, Name = "Rita", grade = 99 });
studentsList .Add(new Student { ID = 102, Name = "Mark", grade = 48 });
Student.failed(studentsList, std => std.grade < 60); // with Lamda
}
}
private static bool isFaildMethod(Student myStudent)//没有Lambda
{
if(myStudent.grade&lt; 60)
{
return true;
}
else
{
return false;
}
}