作为委托的Lambda表达式
Func<int> func = delegate() { return 1; };
Func<int,int> func2 = delegate (int x) { return x+1; };
Func<int> func3 = () => 1;
Func<int, int> func4 = (x) => x + 1;
Func<int, int> func5 = (x) =>
{
int a = 5;
return x + a +1;
};
高阶函数,Lambda表达式的主体本身可以包含另一个Lambda表达式。Lambda表达式的参数可以是另一个委托。
使用委托
var films = new List<Film>
{
new Film {Name = "Jaws", Year = 1975},
new Film {Name = "Bean", Year = 1985},
new Film {Name = "Zan", Year = 1995},
new Film {Name = "Bean", Year = 2005},
};
Action<Film> print = film => Console.WriteLine($"Name={film.Name},Year={film.Year}");
films.ForEach(print);
films.FindAll(film => film.Year < 2000).ForEach(print);
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
表达式树
以编程方式构建表达式树
定义:对象构成的树,树中的每个节点本身都是一个表达式。不同的表达式类型代表能在代码中执行不同的操作。
Type:代表表达式求值后的.Net类型,可视为一个返回类型
NodeType:返回所代表的表达式的种类
将C#Lambda表达式转换成表达式树
Expression<Func<int>> return5 = () => 5;
Func<int> compiled = return5.Compile();
Console.WriteLine(compiled());
限制:
只有对单个表达式进行求值的Lamnda表达式才可以(含有return语句的都不可以)。
表达式树的意义
表达式树的作用是将传统的不可传递的表达式转换成可传递的表达式。表达式树不是一种表达式,而是一种数据结构,该数据结构可以被不同的组织和语言所解析,应用最多的就是LINQ to SQL。猜想:不同的数据库对应的有一个表达式树解析库,这个库可以将.net传递过来的表达式树解析成sql语句。其实这又是建立了一个中间层(表达式树),这个中间层连接着.net和数据库,将2个完全不同的东西通过这个表达式串联起来了。.net这一层面的表达式树的构造是统一的(不管底层的数据库结构是什么样的),而数据库这一层面对表达式树的解析是各自的(所以在ef core中每一种数据库有各自的包)。
在使用LINQ to Objects不需要构造表达式树,直接用lambda表达式(可以用,但没必要)
小结
Lambda表达式完全取代了匿名方法。