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 ...
随机推荐
- kali linux /etc/apt/source.list
this list is very important , you can not download what you want like fictx , flash-plugin , vm-tool ...
- webpack 安装流程
我最近想看看wabpack,然后就面临着安装的问题,说实话,我一点也不懂cmd,怎么还需要用cmd安装呢.其实看教程上说可以在npm上安装,但是我打开npm总是出现闪退,所以我就选择了cmd 安装的过 ...
- Java实现读取文章中重复出现的中文字符串
在上个星期阿里巴巴一面的时候,最后面试官问我如何把一篇文章中重复出现的词或者句子找出来,当时太紧张,答的不是很好.今天有时间再来亲手实现一遍.其实说白了也就是字符串的处理,所以难度并不是很大. 以下是 ...
- javascript中的字符串编码、字符串方法详解
js中的字符串是一种类数组,采用UTF-16编码的Unicode字符集,意味字符串的每个字符可用下标方式获取,而每个字符串在内存中都是一个16位值组成的序列.js对字符串的各项操作均是在对16位值进行 ...
- pyqt系列原创入门教程
pyqt4入门教程 python pyqt4 PyQt是一个创建GUI应用程序的工具包.它是Python编程语言和Qt库的成功融合.Qt库是目前最强大的库之一. 通过pyqt可以实现很多我们想要的功能 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 17.支持实时数据库,高并发保存测点数据。附:3.4 发布与版本更新说明。
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- C# 索引同时含有数字和字符串的集合 同时具备IList和IDictionary的特点
同时具备IList和IDictionary的特点的集合 [Serializable] public class MyCollection:IList { private readonly Dictio ...
- post和get请求的区别
post和get请求的区别: 1.post发送的数据在请求体中,用户看不到 get发送的数据在地址栏中 2.post请求中有content-type,作用是告诉服务器,发送给服务器的数据格式,是和ur ...
- Dubbo的配置及使用
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- Redis基础学习(五)—Redis的主从复制
一.概述 Redis的主从复制策略是通过其持久化的rdb文件来实现的,其过程是先dump出rdb文件,将rdb文件全量传输给slave,然后再将dump后的操作实时同步到slave中.让从服务 ...