Lambda表达式和Lambda表达式树
#region 9-1用匿名方法来创建委托实例 Func<string, int> returnLength;//等价public delegate int SomeDelegate(string arg1)。当返回void时,使用Action<>系列委托 returnLength = delegate(string text) { return text.Length; }; Console.WriteLine(returnLength("Holle")); #endregion #region 9-2冗长的第一个Lambda表达式 Func<string, int> returnLength; returnLength = (string text) => { return text.Length; }; returnLength = (string text) => text.Length;//用单一表达式做为主体 returnLength = (text) => text.Length;//隐式类型的参数列表 returnLength = text => text.Length;//单一参数的快捷语法 Console.WriteLine(returnLength("Holle")); #endregion #region 9-4用Lambda处理一个电影列表 var films = new List<Film> { new Film{Name="Jaws1",Year=1975}, new Film{Name="Jaws2",Year=1975}, new Film{Name="Jaws5",Year=1975}, new Film{Name="Jaws4",Year=1976}, }; Action<Film> print = film => Console.WriteLine("Name={0},Year={1}", film.Name, film.Year); films.ForEach(print);//打印全部元素 films.FindAll(film => film.Year > 1975).ForEach(print);//过滤打印 films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));//排序打印 films.ForEach(print); #endregionpublic partial class Form1 : Form { public Form1() { InitializeComponent(); Button button = new Button { Text = "Click me" }; button.Click += (src, e) => Log("Click", src, e); button.KeyPress += (src, e) => Log("KeyPress", src, e); button.MouseClick+=(src,e)=>Log("MouseClick",src,e); Form form = new Form { AutoSize = true, Controls = { button } }; Application.Run(form); } static void Log(string title, object sender, EventArgs e) { Console.WriteLine("Event:{0}", title); Console.WriteLine("Sender:{0}", sender); Console.WriteLine("Argument:{0}", e); foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(e)) { string name = prop.DisplayName; object value = prop.GetValue(e); Console.WriteLine(" {0}={1}", name, value); } } static void Log(string title, object sender) { Console.WriteLine("Event:{0}", title); Console.WriteLine("Sender:{0}", sender); } }- Type属性代表表达式求值后的.NET类型
- NodeType属性返回所代表的表达式种类
#region 9-6一个非常简单的表达式树 //System.Linq.Expressions命名空间包含了代表表达式的各个类,他们都继承至Expression Expression firstArg = Expression.Constant(2); Expression secondArg = Expression.Constant(3); Expression add = Expression.Add(firstArg, secondArg); Console.WriteLine(add); #endregion

#region 9-7编译并执行一个表达式 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()); #endregion #region 9-8用Lambda表达式转换成表达式树 Expression<Func<int>> return5 = () => 5;//Lambda表达式 Func<int> compiled1 = return5.Compile(); Console.WriteLine(compiled1()); #endregion#region 9-9演示一个更复杂的表达式树 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")); #endregion
#region 9-10用代码来构造一个方法调用表达式树 MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });//获取方法名为StartsWith,参数为string的公共方法 var target = Expression.Parameter(typeof(string), "x"); var methodArg = Expression.Parameter(typeof(string), "y"); Expression[] methodArgs = new[] { methodArg }; //Call(Expression instance, MethodInfo method, params Expression[] arguments) Expression call = Expression.Call(target, method, methodArgs);//x.StartsWith(y),以上部件创建CallExpression var lambdaParameters = new[] { target, methodArg };//这里使用的参数顺序就是调用委托所使用的参数顺序 var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters);//(x,y)=>x.StartsWith(y),lambdaParameters填充call集合 var compiled = lambda.Compile();//生成lambda表达式的委托 Console.WriteLine(compiled("First", "csend")); Console.WriteLine(compiled("First", "Fir")); #endregion #region 9-11 需要新的类型推断规则例子(用Lambda表达式调用一个泛型方法) static void PrintConvertedValue<TInput, TOutput>(TInput input, Converter<TInput, TOutput> converter) { Console.WriteLine(converter(input)); } #endregion #region 9-11 PrintConvertedValue("I'm a string", x => x.Length);//C#2中,编译将失败,C#2类型推断单独针对每一个实参来进行的,从一个实参无法推断出另一个实参 #endregion #region 9-13根据一天当中的时间来选择返回int或object delegate T MyFunc<T>(); static void WriteResult<T>(MyFunc<T> function) { Console.WriteLine(function()); } #endregion #region 9-13 WriteResult(delegate { if (DateTime.Now.Hour < 22)//int { return 10; } else//object { return new object(); } });//编译器采用处理隐式数组的逻辑处理返回类型,对int进行了装箱,返回类型为object #endregion #region 9-14综合来自多个实参的信息,灵活地进行类型推断 static void PrintType<T>(T first, T second)//被强制转换为具体类型参数的最终固定变量类型 { Console.WriteLine(typeof(T)); } #endregion #region 9-14 PrintType(1,new object());//返回类型推断为object类型 #endregion
#region 9-15多级类型推断 static void ConvertTwice<TInput, TMiddle, TOutput>(TInput input, Converter<TInput, TMiddle> firstConversion, Converter<TMiddle, TOutput> secondConversion) { TMiddle middle = firstConversion(input); TOutput output = secondConversion(middle); Console.WriteLine(output); } #endregion #region 9-15 //第一阶段,编译器处理普通实参,得到TInput类型string,第一次执行阶段二,TInput固定为string类型,推断TMiddle为int,再次执行第二阶段,TMiddle固定为int,TOutput为double,推断结束 //lambda表达式主体只有在输入参数的类型已知后才能进行检查 ConvertTwice("Another string", text => text.Length, length => Math.Sqrt(length)); #endregion #region 9-16委托返回类型影响了重载选择 //如果一个匿名函数能转换成参数列表相同,但返回类型不同的两个委托类型,就根据从“推断的返回类型”到“委托的返回类型”的转换来判断哪个委托转换好 static void Execute(Func<int> action) { Console.WriteLine("action return an int:" + action()); } static void Execute(Func<double> action) { Console.WriteLine("action return a douban:" + action()); } #endregion #region 9-16 Execute(() => 1); #endregion
Lambda表达式和Lambda表达式树的更多相关文章
- 委托、匿名委托、Lambda 表达式、Expression表达式树之刨根问底
本篇不是对标题所述之概念的入门文章,重点在阐述它们的异同点和应用场景.各位看官,这里就不啰嗦了,直接上代码. 首先定义一个泛型委托类型,如下: public delegate T Function&l ...
- C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- (转) Lambda表达式中的表达式lambda和语句lambda区别
Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...
- Lambda表达式中的表达式lambda和语句lambda区别
Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...
- C#3.0之神奇的Lambda表达式和Lambda语句
“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型.所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to” ...
- Linq表达式、Lambda表达式你更喜欢哪个?
什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...
- Linq表达式和Lambda表达式用法对比
什么是Linq表达式?什么是Lambda表达式?前一段时间用到这个只是,在网上也没找到比较简单明了的方法,今天就整理了一下相关知识,有空了再仔细研究研究 public Program() { List ...
- lambda表达式和查询表达式
(1)Lambda表达式定义: Lambda是创建匿名函数的另一种形式.它比对应的匿名方法更加的简化.因此,所有的情况都推荐使用Lambda表达式. 它可以包括表达式和语句,并且用于创建委托和事件 ...
- 匿名函数 lambda表达式(lambda expression)
阅读g2log时,发现有两行代码居然看不懂. 1. auto bg_call = [this, log_directory]() {return pimpl_->backgroundChang ...
随机推荐
- Yii2 Pjax 与 ActionForm ,不刷新提交数据
<?php yii\widgets\Pjax::begin(['id'=>'phoneDetail']);?> <?php $form = ActiveForm::begin( ...
- 009 Java集合浅析4
前面一篇教程中,我们分析了List派别中的最常见也最重要的一个类ArrayList<E>.从我们的分析来看,ArrayList作为动态数组的模拟,使用的是连续内存空间来存储数据,带来了可随 ...
- Fundebug上线Node.js错误监控啦
作为全栈JavaScript错误实时监测平台,Fundebug的Node.js实时错误监测服务上线啦,我们能够帮助开发者及时,高效地发现并且解决Node.js错误,从而提高开发效率,并提升用户体验. ...
- ICC_lab总结——ICC_lab4:时钟树综合
时钟树综合的理论知识总结在这里:http://www.cnblogs.com/IClearner/p/6580034.html 下面是实践环节:使用ICC进行时钟树综合. 这个实验的目标是: ·设置C ...
- Frame框架
框架 frameset 框架集 如果使用框架集,当前页面不能有body cols="300,*" :左右拆分,左边宽300,右边宽剩余 rows=" ...
- 《Django By Example》第十二章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第十二章,全书最后一章,终于到这章 ...
- Mybatis 中一对多,多对一的配置
现在有很多电商平台,就拿这个来说吧.顾客跟订单的关系,一个顾客可以有多张订单,但是一个订单只能对应一个顾客. 一对多的顾客 <?xml version="1.0" encod ...
- 序列化与反序列化的单例模式实现和readResolve()
如: public class SingleTest implements Serializable{private static final long serialVersionUID = -860 ...
- 【Electron】Electron开发入门(五):项目打包
一.安装 electron-packager PS:安装之前,先复制一份package.json文件到./app目录下,然后改下./app目录下package.json里 "main&quo ...
- 自动化测试培训:qtp脚本获取获取汇率数据
poptest(www.poptest.cn)致力于测试开发工程师的培训,以培养能胜任做测试工具开发,完成自动化测试,性能测试,安全性测试等工作能力为目标.自8月份成立2个月内中针对企业在职人员的能力 ...