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);
#endregion
public 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 ...
随机推荐
- ubuntu 虚拟机vm virtualbox 不能打开 win7
ubuntu某方面总有些不便,下载个虚拟机装个win7 但是第二次打开的时候就出现了安装是的场景: 原因很简单: 是因为安装了之后没有把win7的镜像文件移除,每次打开时会检测cd/dvd文件/(is ...
- 关于EasyUI 1.5版Datagrid组件在空数据时无法显示"空记录"提示的BUG解决方法
问题:jQuery easyUI中Datagrid,在表格数据加载无数据的时候,如何显示"无记录"的提示语? 解决jQuery EasyUI 1.5.1版本的Datagrid,在处 ...
- 使用Yeoman generator来规范工程的初始化
前言 随着开发团队不断发展壮大,在人员增加的同时也带来了协作成本的增加:业务项目越来越多,类型也各不相同.常见的类型有基础组件.业务组件.基于React的业务项目.基于Vue的业务项目等等.如果想要对 ...
- AE + GDAL实现影像按标准图幅分割(上)
最近有个项目,其中有个功能是要将遥感影像按标准图幅分割,一开始用AE的接口,慢的让人抓狂,就改用GDAL,速度提升很大.我主要通过http://blog.csdn.net/liminlu0314/学习 ...
- 函数调用过程&生成器解释
摘自马哥解答,感谢. 函数调用过程: 假设程序是单进程,单执行流,在某一时刻,能运行的程序流只能有一个.但函数调用会打开新的执行上下文,因此,为了确保main函数可以恢复现场,在main函数调用其它函 ...
- 重温Javascript(一)
工作中要用到JavaScript,一组复习笔记. 一些看法 1. 想想JavaScript目前最常用的宿主环境,浏览器或者服务端V8,都是单线程,所以不用过多的考虑并发的问题,如果是协程来实现异步的方 ...
- 在ASP.NET Core中使用Apworks快速开发数据服务
不少关注我博客的朋友都知道我在2009年左右开发过一个名为Apworks的企业级应用程序开发框架,旨在为分布式企业系统软件开发提供面向领域驱动(DDD)的框架级别的解决方案,并对多种系统架构风格提供支 ...
- VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)
一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...
- scrollWidth,offsetWidth,clientWidth,width;scrollHeight,offsetHeight,clientHeight,height;offsetTop,scrollTop,top;offsetLeft,scrollLeft,left还有谁
题中的那么多属性让人头都大了,他们到底是什么意思?不同浏览器的实现是一样的吗?以下所有结论来自chrome版本 53.0.2785.89 (64-bit)和firefox版本52.0.2,操作系统ub ...
- js控制滚动条默认在底部
html: <div id="chat_content" class="chat_content"> < ...