从Delegate,匿名方法到Lamdba表达式
来源:互联网 发布:得失寸心知什么意思 编辑:程序博客网 时间:2024/04/30 18:29
首先看下面的数据集合:
class Employee
{
public string id { set; get; }
public string name { set; get; }
}
List<Employee> lists = new List<Employee>()
{
new Employee(){ id="1001", name="Ivan"},
new Employee(){ id="1002", name="IT"},
new Employee(){ id="1003", name="ISD"},
new Employee(){ id="1004", name="SE"},
new Employee(){ id="1005", name="CI"},
};
如果想要从中找到id=1003的记录,我们可以利用泛型集合List的Find方法。由于此方法参数为一个Predicate代理,所以就产生了下面的代码:
//委托
Predicate<Employee> pre = new Predicate<Employee>(isMary);
Employee emp = lists.Find(pre);
Console.WriteLine(emp.id + "---" + emp.name);
private static bool isMary(Employee emp)
{
return emp.id == "1003";
}
想来这样也是可以达到目的的,但起始还可以简化代码:运用c# 2.0 的特性:匿名方法:
//匿名方法
Employee e = lists.Find(delegate(Employee info) { return info.id == "1003"; });
Console.WriteLine(e.id + "----" + e.name);
用匿名方法简化了代码,替代了委托的定义。
而在C#3.X中,我们还可以利用Lamdba表达式进一步优化代码,而其更简洁:
Employee e2 = lists.Find(info => info.id == "1003");
Console.WriteLine(e2.id + "---" + e2.name);
注意:lamdba表达式: 参数列表(显示或者隐式)+“=》”+表达式
上面的演变过程,我们通过反编译可以看到不管是匿名方法,还是lamdba表达式,编译器实际上为我们做了“生成相关代理”的动作,或者说其实际的执行还是通过代理实现的。而整个演变只不过是为开发者开发方便而进行的“前台”“改进”。
下面通过lamdba表达式在LINQ中的应用来说明这一点:
static void Main()
{
string[] arrs = new string[] { "M001","K001","M002","L021","M001","M003"};
//采用代理做法
Func<string, bool> pre = new Func<string, bool>(getStr);
var result = from item in arrs.Where(pre)
select item;
//采用匿名方法
var result2 = from item in arrs.Where(delegate(string s) { return s.StartsWith("M"); })
select item;
//采用lamdba表达式
var result3 = from item in arrs.Where(s=>s.StartsWith("M"))
select item;
foreach (string s in result)
{
Console.WriteLine(s);
}
}
private static bool getStr(string s)
{
return s.StartsWith("M");
}
IL:
==================代理方式======================
L_0034: ldftn bool LINQDemo.LamdbaDemo::isMary(class LINQDemo.Employee)
L_003a: newobj instance void [mscorlib]System.Predicate`1<class LINQDemo.Employee>::.ctor(object, native int)
L_003f: stloc.1
L_0040: ldloc.0
L_0041: ldloc.1
L_0042: callvirt instance !0 [mscorlib]System.Collections.Generic.List`1<class LINQDemo.Employee>::Find(class [mscorlib]System.Predicate`1<!0>)
L_0047: stloc.2
L_0048: ldloc.2
L_0049: callvirt instance string LINQDemo.Employee::get_id()
L_004e: call void [mscorlib]System.Console::WriteLine(string)
L_0053: nop
L_0054: ret
======================匿名方法==========================
L_0030: ldsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_0035: brtrue.s L_004a
L_0037: ldnull
L_0038: ldftn bool LINQDemo.LamdbaDemo::<Main>b__2(class LINQDemo.Employee)
L_003e: newobj instance void [mscorlib]System.Predicate`1<class LINQDemo.Employee>::.ctor(object, native int)
L_0043: stsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_0048: br.s L_004a
L_004a: ldsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_004f: callvirt instance !0 [mscorlib]System.Collections.Generic.List`1<class LINQDemo.Employee>::Find(class [mscorlib]System.Predicate`1<!0>)
L_0054: stloc.1
L_0055: ldloc.1
L_0056: callvirt instance string LINQDemo.Employee::get_id()
L_005b: call void [mscorlib]System.Console::WriteLine(string)
L_0060: nop
L_0061: ret
=====================lamdba表达式==========================
L_0030: ldsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_0035: brtrue.s L_004a
L_0037: ldnull
L_0038: ldftn bool LINQDemo.LamdbaDemo::<Main>b__2(class LINQDemo.Employee)
L_003e: newobj instance void [mscorlib]System.Predicate`1<class LINQDemo.Employee>::.ctor(object, native int)
L_0043: stsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_0048: br.s L_004a
L_004a: ldsfld class [mscorlib]System.Predicate`1<class LINQDemo.Employee> LINQDemo.LamdbaDemo::CS$<>9__CachedAnonymousMethodDelegate3
L_004f: callvirt instance !0 [mscorlib]System.Collections.Generic.List`1<class LINQDemo.Employee>::Find(class [mscorlib]System.Predicate`1<!0>)
L_0054: stloc.1
L_0055: ldloc.1
L_0056: callvirt instance string LINQDemo.Employee::get_id()
L_005b: call void [mscorlib]System.Console::WriteLine(string)
L_0060: nop
L_0061: ret
========================生成的匿名方法===========
.method private hidebysig static bool <Main>b__2(class LINQDemo.Employee info) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.maxstack 2
.locals init (
[0] bool CS$1$0000)
L_0000: ldarg.0
L_0001: callvirt instance string LINQDemo.Employee::get_id()
L_0006: ldstr "1001"
L_000b: call bool [mscorlib]System.String::op_Equality(string, string)
L_0010: stloc.0
L_0011: br.s L_0013
L_0013: ldloc.0
L_0014: ret
}
==========
lamdba表达式代表一个内嵌的方法,(指向一个匿名的方法),可以传入任何接受delgegate型别的东西,大量用于LINQ中应用到任何匿名方法可以应用的场合,编译器会把lamdba表达式翻译成使用代理的匿名方法。
- 从Delegate,匿名方法到Lamdba表达式
- 匿名函数与lamdba表达式
- 从委托到匿名方法,再到Lambda表达式
- Lamdba表达式
- C#高级程序设计(一)——从接口到代理到匿名方法到lambda表达式
- Java8 Lamdba表达式 001
- Java8 Lamdba表达式 002
- Java8 Lamdba表达式 003
- C++ Lamdba表达式
- c++ lamdba表达式
- lamdba表达式学习
- 关于lamdba表达式
- C#中新特性的学习:Delegate、匿名方法、lambda表达式
- C# 入门(9) 委托(delegate),匿名方法,Lambda表达式
- 使用Lamdba 表达式 从A集合中去除不存在于B集合的元素加入到C集合中(快速找出两个集合中不同的元素)
- 匿名方法、Lambda表达式
- 匿名方法 Lambda表达式
- Delegate,Action,Func,匿名方法,匿名委托,事件
- 硝酸工业,硝酸制作方法
- 用自信克服恐惧心理——职场人士寓言(15)
- 第一次开博
- 6个故事:都体会了你就是营销超人!
- 周易图集收藏
- 从Delegate,匿名方法到Lamdba表达式
- 何去何从
- 一个不错的网站推荐.专门查找java所需要用到的.jar包
- 谭浩强《C语言程序设计(第二版)》的前50页中的错误分析
- Classic First Law
- .NET 学习网站汇总
- Lucene txt搜索引擎
- 回归!!
- 志向