C# in Depth Third Edition 学习笔记-- Lambda表达式和表达式树
2014-08-07 14:13
761 查看
作为委托的Lambda表达式:
Func<....>委托类型: 在.Net 3.5中有以下5个
例如Func<string,double,int> 等价于public delegate int SomeDelegate(string arg1, double arg2)。
如果感觉4个参数太少不够用,在.Net 4中Action<.......>和Func<....>最多可以拥有16个参数。
![](http://images.cnitblog.com/i/576499/201408/011024426495090.png)
使用List<T>和事件的简单例子
//private static bool SomeAutoGeneratedName(Film film)
//{
//return film.Year < 1960;
//}
表达式树Expression trees
code as data将代码作为数据,JIT将IL代码视为数据,并把它们转换成能在某个cpu上运行的本地代码。
以编程方式构建表达式树:
表达式树由对象构成的树,树中每个节点本身就是一个表达式。不同的表达式类型代表能在代码中执行的不同操作:二元操作(例如加法),一元操作(例如获取一个数组的长度),方法调用,构造函数的调用,等等。
一个简单的表达式树,2和3相加
![](http://images.cnitblog.com/i/576499/201408/071032493654151.png)
在表达式树中叶子最先被创建:自下而上构建了这些表达式树。
将表达式树编译成委托:(下面是类的继承关系)
![](http://images.cnitblog.com/i/576499/201408/071038109595532.png)
将C#lambda表达式转换成表达式树:(下面两段代码是等价的,第二个代码段是使用代码生成的第一个代码段的表达式)
![](http://images.cnitblog.com/i/576499/201408/071056442257176.png)
位于LINQ核心的表达式树:
Func<....>委托类型: 在.Net 3.5中有以下5个
TResult Func<TResult>() TResult Func<T,TResult>(T arg) TResult Func<T1,T2,TResult>(T1 arg1, T2 arg2) TResult Func<T1,T2,T3,TResult>(T1 arg1, T2 arg2, T3 arg3) TResult Func<T1,T2,T3,T4,TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
例如Func<string,double,int> 等价于public delegate int SomeDelegate(string arg1, double arg2)。
如果感觉4个参数太少不够用,在.Net 4中Action<.......>和Func<....>最多可以拥有16个参数。
// 使用匿名方法创建委托实例 Func<string,int> returnLength; returnLength = delegate (string text) { return text.Length; }; Console.WriteLine(returnLength("Hello")); // 第一个冗长的Lambda表达式 Func<string,int> returnLength; returnLength = (string text) => { return text.Length; }; Console.WriteLine(returnLength("Hello")); // (显示类型的参数列表)=>表达式 (string text) => text.Length // (隐式类型的参数列表)=>表达式 (text) => text.Length // 参数名=>表达式 text => text.Length
![](http://images.cnitblog.com/i/576499/201408/011024426495090.png)
使用List<T>和事件的简单例子
class Film { public string Name { get; set; } public int Year { get; set; } } ... var films = new List<Film> { new Film { Name = "Jaws", Year = 1975 }, new Film { Name = "Singing in the Rain", Year = 1952 }, new Film { Name = "Some like it Hot", Year = 1959 }, new Film { Name = "The Wizard of Oz", Year = 1939 }, new Film { Name = "It's a Wonderful Life", Year = 1946 }, new Film { Name = "American Beauty", Year = 1999 }, new Film { Name = "High Fidelity", Year = 2000 }, new Film { Name = "The Usual Suspects", Year = 1995 } }; Action<Film> print = film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year); films.ForEach(print); films.FindAll(film => film.Year < 1960).ForEach(print); // 被编译成如下方法
//private static bool SomeAutoGeneratedName(Film film)
//{
//return film.Year < 1960;
//}
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name)); films.ForEach(print);
表达式树Expression trees
code as data将代码作为数据,JIT将IL代码视为数据,并把它们转换成能在某个cpu上运行的本地代码。
以编程方式构建表达式树:
表达式树由对象构成的树,树中每个节点本身就是一个表达式。不同的表达式类型代表能在代码中执行的不同操作:二元操作(例如加法),一元操作(例如获取一个数组的长度),方法调用,构造函数的调用,等等。
一个简单的表达式树,2和3相加
Expression firstArg = Expression.Constant(2); Expression secondArg = Expression.Constant(3); Expression add = Expression.Add(firstArg, secondArg); Console.WriteLine(add);
![](http://images.cnitblog.com/i/576499/201408/071032493654151.png)
在表达式树中叶子最先被创建:自下而上构建了这些表达式树。
将表达式树编译成委托:(下面是类的继承关系)
![](http://images.cnitblog.com/i/576499/201408/071038109595532.png)
Expression firstArg = Expression.Constant(2); Expression secondArg = Expression.Constant(3); Expression add = Expression.Add(firstArg, secondArg); Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile(); Console.WriteLine(compiled());
将C#lambda表达式转换成表达式树:(下面两段代码是等价的,第二个代码段是使用代码生成的第一个代码段的表达式)
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y); var compiled = expression.Compile(); Console.WriteLine(compiled("First", "Second")); Console.WriteLine(compiled("First", "Fir"));
MethodInfo method = typeof(string).GetMethod ("StartsWith", new[] { typeof(string) }); var target = Expression.Parameter(typeof(string), "x"); var methodArg = Expression.Parameter(typeof(string), "y"); Expression[] methodArgs = new[] { methodArg }; Expression call = Expression.Call(target, method, methodArgs); var lambdaParameters = new[] { target, methodArg }; var lambda = Expression.Lambda<Func<string, string, bool>> (call, lambdaParameters); var compiled = lambda.Compile(); Console.WriteLine(compiled("First", "Second")); Console.WriteLine(compiled("First", "Fir"));
![](http://images.cnitblog.com/i/576499/201408/071056442257176.png)
位于LINQ核心的表达式树:
![](http://images.cnitblog.com/i/576499/201408/071058173181217.png)
相关文章推荐
- C# in Depth Third Edition 学习笔记-- C#2.0: 解决C#1.0的问题 1 泛型
- C# in Depth Third Edition 学习笔记-- 值类型和引用
- C# in Depth Third Edition 学习笔记-- C#2的一些特性
- C# in Depth Third Edition 学习笔记-- 可空类型
- 大马哈鱼的C#学习笔记(1):lambda表达式
- C#学习笔记二:并行编程基础:在 PLINQ 和 TPL 中的 Lambda 表达式
- 学习笔记之Lambda 表达式(C# 编程指南)
- 学习笔记之在 LINQ 外部使用 Lambda 表达式(C# 编程指南)
- C# Lambda表达式学习笔记
- 学习笔记之在查询中使用 Lambda 表达式(C# 编程指南)
- 黑马程序员之C#学习笔记: Lambda表达式学习总结
- C#特性 学习笔记(Lambda表达式 迭代)
- C# In Depth Third Edition
- C#学习笔记一:委托、匿名函数、Lambda 表达式
- C#学习笔记 - Lambda表达式
- concurrency runtime学习笔记之一:Lambda表达式
- “Effective C++ Third Edition”学习笔记(四)
- [研究笔记]Lambda表达式学习笔记
- Silverlight学习笔记(三)-----【转】Silverlight 4 in C# - Silverlight的布局管理