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 ...
随机推荐
- Spring还使用基于 JSR-250 注释,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释
@PostConstruct 和 @PreDestroy 注释: 你可以使用 @PostConstruct 注释作为初始化回调函数的一个替代,@PreDestroy 注释作为销毁回调函数的一个替代,其 ...
- ADO.NET温习(一)
ADO.NET概述 本节复习如何使用ADO.NET访问C#程序中的数据,主要介绍如何使用SqlConnection类和OleDbConnection类连接数据库,以及断开与数据库连接.深入讨论命令对象 ...
- C++标准库之stack(各函数及其使用全)
原创作品,转载请注明出处:http://www.cnblogs.com/shrimp-can/p/5283207.html 栈是后入先出的.成员函数有: 1.栈的声明 std::deque<in ...
- 源码分析——从AIDL的使用开始理解Binder进程间通信的流程
源码分析——从AIDL的使用开始理解Binder进程间通信的流程 Binder通信是Android系统架构的基础.本文尝试从AIDL的使用开始理解系统的Binder通信. 0x00 一个AIDL的例子 ...
- iOS开发之数据存储之Preference(偏好设置)
1.概述 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能. 每个应用都有个NSUserDefaults实例,通过它来存取偏好 ...
- 移动web页面支持弹性滚动的3个方案
有段时间一直折腾移动端页面弹性滚动的各种问题,做了点研究,今天做个小分享~ 传统 pc 端中,子容器高度超出父容器高度,通常使用 overflow:auto 可出现滚动条拖动显示溢出的内容,而移动we ...
- Apache优化
控制MaxClients的设置,以避免服务器产生太多的子进程而发生交换.进程间的数据交换会占用很大内存,数据交换产生的滞后使用户总感觉"不够快",所以用户就可能去按"停止 ...
- C#研究OpenXML之路(3-OpenXMLSDKToolV25.msi)
一.OpenXMLSDKToolV25.msi 看了几天的OpenXml,感觉如果完全手写代码,将会是一件非常苦逼的事情,即要分析对应xlsx文件层次结构,以及包含的xml文件的xml标签结构,还要关 ...
- LoadRunner性能测试专项班隆重开班
LoadRunner性能测试专项班隆重开班 POPTEST首届高级性能测试提升强化班开课. 也许你只是看到成功者的光鲜,却没看到他们的努力和汗水.不要否定现在,要看到未来.提高自己.怎么自己.成就自己 ...
- [Python Web]配置 nginx 遇到错误排查(初级)
配置 nginx 遇到错误排查(初级) 系统版本:ubuntu 14.04,nginx 版本:nginx/1.4.6 (Ubuntu) 本文不是一步步搭建 nginx 的过程,而是我在使用 nginx ...