对于C#中的Expression天性想必从事C#支付的同桌都不会面生,英特网和田园里都有繁多的好的小说介绍。我想也未尝要求再去写一些稿子去介绍,科学普及或是从入门到精晓之类的。

Expression经验在此之前言,Expression经验

对于C#中的Expression脾气想必从事C#支付的同班都不会素不相识,网络和田园里都有大多的好的小说介绍。作者想也未曾要求再去写一些篇章去介绍,科学普及或是从入门到精晓之类的。

那多种的小说首假如就得以落成职业和读书进程中的一些心想、难点的缓慢解决以及自觉风趣的意识等作些分享。

借助于Expression, 大家能够写些很优雅(至少个人感到)的代码。

例于开拓WPF的同桌们每日要接触的ViewModel中,

OnPropertyChanged(() => Name);

要比

OnPropertyChanged("Name")

雅淡。并且越来越多的益处是能够在编写翻译时检查错误,越发是在Property名字被更换后。

 

好了,对Expression的赞许就不多说了。以下是自己想分享的经历:

Expression经验之壹:合并拉姆daExpression

Expression经验之贰:LambdaExpression转变

Expression经验之3:拉姆daExpression作缓存key

 

对于C#中的Expression特性想必从事C#支付的校友都不会面生,英特网和田园里都有不少的好的小说介绍。我想…

对于C#中的Expression个性想必从事C#开采的校友都不会素不相识,网上和田园里都有众多的好的篇章介绍。小编想也从未要求再去写一些文章去介绍,科学普及或是从入门到通晓之类的。

较以前三个本子,对于C# 三.x和VB 玖来讲,LINQ是最具吸重力的。基本上许多的新的特色都以环绕着LINQ的贯彻来统筹的。借助Extension
Method,大家可感觉LINQ定义壹体系的Operator。通过拉姆da Expression大家得感觉LINQ编写特别从简的查询。大家能够说这一个新的特征成就了LINQ,也得以说那一个新本性就是为着兑现LINQ而发出,可是大家理应知道,对于那个新引进的特色,LINQ并非他们唯一的用武之地,在形似的编制程序中,我们也得以动用它们。

那种类的小说首即便就落实专门的学业和读书进度中的一些构思、难题的缓和以及自觉有意思的觉察等作些分享。

那接2连三串的小说首就算就兑现专门的学业和读书进程中的一些理念、难点的减轻以及自觉风趣的觉察等作些分享。

继上一章,介绍Extension
Method随后,大家随后来介绍另2个第二的特色:拉姆da
Expression。在前方的两篇小说中,笔者频繁在强调那样的一个定义:C#
叁.x新引进的这一个特点仅仅展现在Programming
Language和对应的Compiler层面。通过编译生成的Assembly的IL和原来并未有实质的更换。从这么些意思上讲,全数的那些实际是编写翻译器给我们玩得障眼法而已。拉姆da
Expression也不例外, Lambda
Expression正是三个Anonymous
Delegate,无论是Named
Delegate也好、Anonymous
Delegate也好,其本质也正是三个Delegate。

借助于Expression, 大家能够写些很优雅(至少个人认为)的代码。

借助于Expression, 大家得以写些很优雅(至少个人以为)的代码。

接下去,笔者将透过多个简便的德姆onstration,由表及里地分析Lambda
Expression,看看编写翻译器到底会编写翻译生成什么样的附加的Code,他们的IL又是怎样。

例于开拓WPF的同校们每日要接触的ViewModel中,

例于开采WPF的同窗们天天要接触的ViewModel中,

一、Named Delegate

OnPropertyChanged(() => Name);
OnPropertyChanged(() => Name);

在上头,我说了Lambda Expression本质上正是一个Delegate,大家先不直接来介绍Lambda
Expression, 大家先来探望大家Infiniti熟知的Delegate的例子: 

要比

要比

金沙注册送58 1using System;
金沙注册送58 2using System.Collections.Generic;
金沙注册送58 3using System.Linq;
金沙注册送58 4using System.Text;
金沙注册送58 5
金沙注册送58 6namespace Artech.LambdaExpression
金沙注册送58 7金沙注册送58 8金沙注册送58 9{
金沙注册送58 10    class Program
金沙注册送58 11金沙注册送58 12    金沙注册送58 13{
金沙注册送58 14        static void Main()
金沙注册送58 15金沙注册送58 16        金沙注册送58 17x的新特点,Expression经验在此之前言。{
金沙注册送58 18            _namedMethodDelegate = new Function<int, bool>(SomeMethod);
金沙注册送58 19            Function<int, bool> function1 = _namedMethodDelegate;
金沙注册送58 20            function1(20);     
金沙注册送58 21
金沙注册送58 22        }
金沙注册送58 23        private static Function<int, bool> _namedMethodDelegate;
金沙注册送58 24
金沙注册送58 25        private static bool SomeMethod(int args)
金沙注册送58 26金沙注册送58 27        金沙注册送58 28{
金沙注册送58 29            return (args > 0);
金沙注册送58 30        }
金沙注册送58 31
金沙注册送58 32    }
金沙注册送58 33
金沙注册送58 34    delegate TResult Function<TArgs, TResult>(TArgs args);
金沙注册送58 35
金沙注册送58 36}

OnPropertyChanged("Name")
OnPropertyChanged("Name")

地点的例子很简短,先定3个Generic Delegate :Function。在Program Class中定义二个Static的Function字段_namedMethodDelegate和与之相应的Method:SomeMethod,判定输入的数字是还是不是超越零。在Main中实例化_namedMethodDelegate,并调用它。

优雅。并且越多的益处是足以在编写翻译时检查错误,尤其是在Property名字被改换后。

清淡。并且愈来愈多的便宜是足以在编写翻译时检查错误,尤其是在Property名字被改成后。

大家经过IL Disassembler那么些Utility来看望Main方法的IL代码。为了让对IL Instruction不是很理解的读者进一步轻巧地掌握整个推行进程,小编加了简约注释。对于这几个梦想越来越询问整个MSIL
Instruction列表的读者,能够参考:MSIL Instruction
Table。

 

 

金沙注册送58 37.method private hidebysig static void  Main() cil managed
金沙注册送58 38金沙注册送58 39金沙注册送58 40{
金沙注册送58 41  .entrypoint
金沙注册送58 42  // Code size       34 (0x22)
金沙注册送58 43  .maxstack  3
金沙注册送58 44  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function1)//Initialize function1
金沙注册送58 45  IL_0000:  nop
金沙注册送58 46  IL_0001:  ldnull
金沙注册送58 47  IL_0002:  ldftn      bool Artech.LambdaExpression.Program::SomeMethod(int32)//Pushes the method pointer referenced by SomeMethod. 
金沙注册送58 48  IL_0008:  newobj     instance void class Artech.LambdaExpression.Function`2<int32,bool>::.ctor(object,
金沙注册送58 49                                                                                                 native int)//Initializer a Artech.LambdaExpression.Function delegate instance.
金沙注册送58 50  IL_000d:  stsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::_namedMethodDelegate//Stores a static field: _namedMethodDelegate
金沙注册送58 51  IL_0012:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::_namedMethodDelegate//Pushes the static field(_namedMethodDelegate)  of an object Static .
金沙注册送58 52  IL_0017:  stloc.0   //Pop the first local variable 
金沙注册送58 53  IL_0018:  ldloc.0   //Pushes the first local variable 
金沙注册送58 54  IL_0019:  ldc.i4.s   20 //Pushes specified 8-bit value (20) as 32-bit 
金沙注册送58 55  IL_001b:  callvirt   instance !1 class Artech.LambdaExpression.Function`2<int32,bool>::Invoke(!0)//Calls virtual method of delegate instance. 
金沙注册送58 56  IL_0020:  pop
金沙注册送58 57  IL_0021:  ret
金沙注册送58 58} // end of method Program::Main
金沙注册送58 59

好了,对Expression的歌颂就不多说了。以下是自家想享受的经验:

好了,对Expression的褒奖就不多说了。以下是自作者想享受的阅历:

对于Delegate,小编无须再作深远的牵线,相信我们早就了如指掌。在那边供给器重建议是,上边介绍的始末将是承继部分的功底,通过后边的对Anonymous
Method和拉姆da expression介绍,你会开掘它们生成的代码结商谈地点的是丰硕相像的。

Expression经验之1:合并LambdaExpression

Expression经验之一:合并LambdaExpression

二、  Anonymous
Method Delegate

Expression经验之2:拉姆daExpression转变

Expression经验之二:拉姆daExpression转换

Anonymous Method是C# 贰.0引进的一个十分好用的意义。通过Anonymous
Method,大家得以Delegate的贯彻直接以Inline的法子放入Delegate对象使用的任务,而无须再繁琐地开创1个Delegate,并通过定义在某些Class中有所同样申明的Method来事例化那些Delegate Instance,最终才将以此delegate instance传入要求调用的Method。

 

 

我们前几天经过Anonymous Method来简化下边包车型客车代码。

金沙注册送58 60using System;
金沙注册送58 61using System.Collections.Generic;
金沙注册送58 62using System.Linq;
金沙注册送58 63using System.Text;
金沙注册送58 64
金沙注册送58 65namespace Artech.LambdaExpression
金沙注册送58 66金沙注册送58 67金沙注册送58 68{
金沙注册送58 69    class Program
金沙注册送58 70金沙注册送58 71    金沙注册送58 72{
金沙注册送58 73        static void Main()
金沙注册送58 74金沙注册送58 75        金沙注册送58 76{
金沙注册送58 77            Function<int, bool> function2 = delegate(int args)
金沙注册送58 78金沙注册送58 79            金沙注册送58 80{
金沙注册送58 81                return args > 0;
金沙注册送58 82            };
金沙注册送58 83            function2(20);   
金沙注册送58 84        }
金沙注册送58 85    }
金沙注册送58 86    delegate TResult Function<TArgs, TResult>(TArgs args);
金沙注册送58 87}
金沙注册送58 88

咱们经过Reflector分析编写翻译生成的Assembly,我们发掘它富有上面包车型地铁组织。进一步分析Program
Class,大家开掘它多了两个附加的Static成员:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。那是编写翻译器的进献。

金沙注册送58 89

下边分别是<>9__CachedAnonymousMethodDelegate1和<Main>b__0的定义:

金沙注册送58 90[CompilerGenerated]

金沙注册送58 91private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

金沙注册送58 92[CompilerGenerated]

金沙注册送58 93private static bool <Main>b__0(int args)

金沙注册送58 94金沙注册送58 95金沙注册送58 96{

金沙注册送58 97    return (args > 0);

金沙注册送58 98}

金沙注册送58 99

是否自己大家地点壹节定义的_namedMethodDelegate和SomeMethod那个多个静态成员平等?  

笔者们进一步分析Main Method的IL。

金沙注册送58 100.method private hidebysig static void  Main() cil managed
金沙注册送58 101金沙注册送58 102金沙注册送58 103{
金沙注册送58 104  .entrypoint
金沙注册送58 105  // Code size       43 (0x2b)
金沙注册送58 106  .maxstack  3
金沙注册送58 107  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function2)
金沙注册送58 108  IL_0000:  nop
金沙注册送58 109  IL_0001:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 110  IL_0006:  brtrue.s   IL_001b
金沙注册送58 111  IL_0008:  ldnull
金沙注册送58 112  IL_0009:  ldftn      bool Artech.LambdaExpression.Program::'<Main>b__0′(int32)
金沙注册送58 113  IL_000f:  newobj     instance void class Artech.LambdaExpression.Function`2<int32,bool>::.ctor(object,
金沙注册送58 114                                                                                                 native int)
金沙注册送58 115  IL_0014:  stsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 116  IL_0019:  br.s       IL_001b
金沙注册送58 117  IL_001b:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 118  IL_0020:  stloc.0
金沙注册送58 119  IL_0021:  ldloc.0
金沙注册送58 120  IL_0022:  ldc.i4.s   20
金沙注册送58 121  IL_0024:  callvirt   instance !1 class Artech.LambdaExpression.Function`2<int32,bool>::Invoke(!0)
金沙注册送58 122  IL_0029:  pop
金沙注册送58 123  IL_002a:  ret
金沙注册送58 124} // end of method Program::Main
金沙注册送58 125

和我们地点一节的IL比较,是不是出奇地一般。所用咱们得以说,大家在第三节中Named
Delegate和Anonymous Method
Delegate是壹模一样的。

接下去我们因而拉姆da Expression落成地点的效率。

三、 Lambda
Expression

上边是透过拉姆da Expression落成地点一样效果的Code:

金沙注册送58 126using System;
金沙注册送58 127using System.Collections.Generic;
金沙注册送58 128using System.Linq;
金沙注册送58 129using System.Text;
金沙注册送58 130
金沙注册送58 131namespace Artech.LambdaExpression
金沙注册送58 132金沙注册送58 133金沙注册送58 134{
金沙注册送58 135    class Program
金沙注册送58 136金沙注册送58 137    金沙注册送58 138{
金沙注册送58 139        static void Main()
金沙注册送58 140金沙注册送58 141        金沙注册送58 142{
金沙注册送58 143            Function<int, bool> function3 = x => x > 0;
金沙注册送58 144            function3(20);
金沙注册送58 145        }
金沙注册送58 146    }
金沙注册送58 147
金沙注册送58 148    delegate TResult Function<TArgs, TResult>(TArgs args);
金沙注册送58 149
金沙注册送58 150}
金沙注册送58 151

作者们透过Reflector分析编写翻译生成的Assembly,大家开掘它和由此Anonymous Method
Delegate落成的完全一致:Program Class,大家开掘它多了五个附加的Static成员,它们的称号都完全平等:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。

金沙注册送58 152

这两个Static Member:<>9__CachedAnonymousMethodDelegate1和<Main>b__0的定义也于我们经过Anonymous Method
Delegate落成时1模同样:

金沙注册送58 153[CompilerGenerated]

金沙注册送58 154private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

金沙注册送58 155

金沙注册送58 156[CompilerGenerated]

金沙注册送58 157金沙注册送58,private static bool <Main>b__0(int args)

金沙注册送58 158金沙注册送58 159金沙注册送58 160{

金沙注册送58 161    return (args > 0);

金沙注册送58 162}

金沙注册送58 163

咱俩更是来探望Main Method的IL。
 

金沙注册送58 164.method private hidebysig static void  Main() cil managed
金沙注册送58 165金沙注册送58 166金沙注册送58 167{
金沙注册送58 168  .entrypoint
金沙注册送58 169  // Code size       43 (0x2b)
金沙注册送58 170  .maxstack  3
金沙注册送58 171  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function3)
金沙注册送58 172  IL_0000:  nop
金沙注册送58 173  IL_0001:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 174  IL_0006:  brtrue.s   IL_001b
金沙注册送58 175  IL_0008:  ldnull
金沙注册送58 176  IL_0009:  ldftn      bool Artech.LambdaExpression.Program::'<Main>b__0′(int32)
金沙注册送58 177  IL_000f:  newobj     instance void class Artech.LambdaExpression.Function`2<int32,bool>::.ctor(object,
金沙注册送58 178                                                                                                 native int)
金沙注册送58 179  IL_0014:  stsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 180  IL_0019:  br.s       IL_001b
金沙注册送58 181  IL_001b:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1′
金沙注册送58 182  IL_0020:  stloc.0
金沙注册送58 183  IL_0021:  ldloc.0
金沙注册送58 184  IL_0022:  ldc.i4.s   20
金沙注册送58 185  IL_0024:  callvirt   instance !1 class Artech.LambdaExpression.Function`2<int32,bool>::Invoke(!0)
金沙注册送58 186  IL_0029:  pop
金沙注册送58 187  IL_002a:  ret
金沙注册送58 188} // end of method Program::Main
金沙注册送58 189

和方面通过

Anonymous Method Delegate实现的时候完全是壹模同样的。

四、Conclusion 

 

近来大家得以得出结论了,拉姆da
Expression本质上是多个Anonymous Method
Delegate,那一个Delegate的无名氏性仅仅针对Programming
language来说,编写翻译器会为它生成一个Named
delegate和一个它指向的Method。这几个三个额外生成的目的作为利用Anonymous
Method Delegate对应的Class的Static Method而留存。从本质上讲和一般的Delegate并未实质的界别。所以地点大家独家通过Named
delegate、Anonymous method
delegate和Lambda
Expression达成的叁个办法是1模同样的。

C# 三.x相关内容:
[原创]深刻掌握C#
三.x的新特色(一):Anonymous
Type
[原创]深入精通C#
叁.x的新特色(二):Extension Method – Part
I
[原创]深入通晓C#
三.x的新特色(二):Extension Method – Part
II
[原创]浓密掌握C# 3.x的新特色(三):从Delegate、Anonymous
Method到拉姆da
Expression
[原创]深远精通C# 叁.x的新特色(四):Automatically Implemented
Property
[原创]深入精晓C# 三.x的新特色(5):Object Initializer 和 Collection
Initializer

相关文章

网站地图xml地图