staticvoidMain(string[] args){
IList<Action> list = new List<Action>();for(int i =0; i <5; i++){
list.Add(()=>{ Console.WriteLine(i);});}foreach(var item in list){item();}
Console.Read();}staticvoidMain(string[] args){
IList<Action> list = new List<Action>();for(int i =0; i <5; i++){int tmp = i;
list.Add(()=>{ Console.WriteLine(tmp);});}foreach(var item in list){item();}
Console.Read();}
public class ClosureBag
{
public int externVariant;
public voidLambda(){
Console.WriteLine(this.externVariant);}}staticvoidMain(string[] args){
IList<Action> list = new List<Action>();
ClosureBag closureBag= new ClosureBag();for(closureBag.externVariant =0; closureBag.externVariant <5; closureBag.externVariant++){
list.Add(closureBag.Lambda);}foreach(var item in list){item();}
Console.Read();}staticvoidMain(string[] args){
IList<Action> list = new List<Action>();for(int i =0; i <5; i++){
ClosureBag closureBag = new ClosureBag();
closureBag.externVariant = i;
list.Add(closureBag.Lambda);}foreach(var item in list){item();}
Console.Read();}
12.5.3 捕捉了循环变量的Lambda表达式
foreach
C#5.0以后,捕捉foreach的循环变量会自动认为是不同的变量
C#5.0之前,读取外部变量最新的数据
for循环
始终读取外部变量最新的数据
解决方式
可以在每次循环中声明一个新的局部变量去接收循环变量的值
classDoNotCaptureLoop{staticvoidMain(){var items =newstring[]{"Moe","Larry","Curly"};var actions =newList<Action>();foreach(string item in items){string _item = item;
actions.Add(()=>{Console.WriteLine(_item);});}foreach(Action action in actions){action();}}}
12.6 表达式树类型
一种数据结构,将Lambda表达式中的表达式Lambda提取成树的结构
只有表达式Lambda才能转换为表达式树,语句Lambda不能转换为表达式树
12.6.1 表达式树的作用
作为数据使用
提取的树结构可以转化成其他查询语言,如SQL
作为对象图
包含参数、返回值类型、主体表达式
12.6.2 委托和表达式树的比较
Lambda表达式可以自动转化为委托类型或者表达式树
委托类型
方法的引用
对于persons.Where( person => person.Name.ToUpper == “INIGO MONTOYA”);而言
若转换为委托,则是方法的调用,persons是从数据库获取所有数据
表达式树
可以转换为SQL
对于persons.Where( person => person.Name.ToUpper == “INIGO MONTOYA”);而言