x的新特色,Expression经验在此之前言

对于C#中的Expression天性想必从事C#支出的同班都不会面生,英特网和田园里都有不少的好的小说介绍。作者想也绝非需求再去写一些篇章去介绍,科普或是从入门到理解之类的。

Expression经验以前言,Expression经验

对于C#中的Expression特性想必从事C#付出的同窗都不会目生,英特网和田园里都有成都百货上千的好的稿子介绍。作者想也远非须要再去写一些文章去介绍,科普或是从入门到领会之类的。

这接二连三串的随笔首若是就兑现专门的工作和上学进程中的一些妄图、难点的消除以及自觉有意思的发掘等作些分享。

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

例于开垦WPF的同窗们每一天要接触的ViewModel中,

OnPropertyChanged(() => Name);

要比

OnPropertyChanged("Name")

优雅。并且更加多的功利是足以在编写翻译时检查错误,越发是在Property名字被改成后。

 

好了,对Expression的表扬就不多说了。以下是笔者想分享的经历:

Expression经验之1:合并LambdaExpression

Expression经验之二:LambdaExpression调换

Expression经验之三:LambdaExpression作缓存key

 

对于C#中的Expression天性想必从事C#支付的同桌都不会素不相识,网络和田园里都有众多的好的稿子介绍。笔者想…

对于C#中的Expression个性想必从事C#支付的同校都不会目生,网络和田园里都有为数不少的好的篇章介绍。小编想也完全没有供给再去写一些小说去介绍,科学普及或是从入门到理解之类的。

较在此之前三个本子,对于C# 3.x和VB 玖来讲,LINQ是最具魅力的。基本上大多的新的性状都以环绕着LINQ的落成来安排的。借助Extension
Method,我们得以为LINQ定义一雨后苦笋的Operator。通过Lambda Expression大家可感到LINQ编写特别简洁的询问。大家得以说那么些新的特色成就了LINQ,也足以说这一个新特征正是为了达成LINQ而发生,但是大家应当了然,对于那个新引进的特征,LINQ并非他们唯一的用武之地,在相似的编制程序中,大家也能够运用它们。

那多种的小说首若是就得以完毕专门的工作和上学进程中的一些思维、难点的化解以及自觉有意思的觉察等作些分享。

那系列的小说主倘若就得以落成工学进程中的一些心想、难点的消除以及自觉风趣的意识等作些分享。

继上1章,介绍Extension
Method事后,我们随后来介绍另3个第一的特色:Lambda
Expression。在前方的两篇小说中,小编一再在强调那样的3个概念:C#
三.x新引进的这个特色仅仅浮未来Programming
Language和相应的Compiler层面。通过编写翻译生成的Assembly的IL和原来并未精神的改变。从这几个含义上讲,全数的那么些实际上是编写翻译器给我们玩得障眼法而已。拉姆da
Expression也不例外, 拉姆da
Expression正是1个Anonymous
Delegate,无论是Named
Delegate也好、Anonymous
Delegate也好,其本质约等于三个Delegate。

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

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

接下去,小编将经过三个粗略的Demonstration,由浅入深地分析Lambda
Expression,看看编写翻译器到底会编写翻译生成什么的额外的Code,他们的IL又是什么。

例于开拓WPF的同学们天天要接触的ViewModel中,

例于开采WPF的同桌们每一天要接触的ViewModel中,

一、Named Delegate

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

在上头,小编说了拉姆da Expression本质上正是叁个Delegate,我们先不直接来介绍拉姆da
Expression, 大家先来探望大家Infiniti熟知的Delegate的例子: 

要比

要比

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

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

地点的例证比极粗略,先定一个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。

 

 

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

好了,对Expression的称道就不多说了。以下是小编想分享的经历:

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

对于Delegate,作者无须再作深刻的牵线,相信大家已经了如指掌。在此间须要注重指出是,上面介绍的始末将是延续部分的基本功,通过前面的对Anonymous
Method和Lambda expression介绍,你会开采它们生成的代码结议和上边的是非凡相像的。

Expression经验之壹:合并LambdaExpression

Expression经验之壹:合并拉姆daExpression

二、  Anonymous
Method Delegate

Expression经验之2:LambdaExpression调换

Expression经验之二:拉姆daExpression转变

Anonymous Method是C# 二.0引进的1个分外好用的法力。通过Anonymous
Method,我们能够Delegate的落到实处直接以Inline的形式放入Delegate对象使用的职位,而无须再繁琐地开创三个Delegate,并经过定义在有些Class中颇具同样表明的Method来事例化这些Delegate Instance,最终才将这几个delegate instance传入要求调用的Method。

 

 

咱俩今日因此Anonymous Method来简化上边包车型大巴代码。

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

大家通过Reflector分析编写翻译生成的Assembly,我们开掘它装有下边的构造。进一步分析Program
Class,大家发掘它多了五个附加的Static成员:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。那是编写翻译器的功绩。

美高梅开户网址 89

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

美高梅开户网址 90[CompilerGenerated]

美高梅开户网址 91private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

美高梅开户网址 92[CompilerGenerated]

美高梅开户网址 93private static bool <Main>b__0(int args)

美高梅开户网址 94美高梅开户网址 95美高梅开户网址 96{

美高梅开户网址 97    return (args > 0);

美高梅开户网址 98}

美高梅开户网址 99

是还是不是作者大家地点1节定义的_namedMethodDelegate和SomeMethod这些三个静态成员一致?  

大家更为分析Main Method的IL。

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

和我们地点一节的IL相比,是不是出奇地相似。所用大家能够说,大家在首先节中Named
Delegate和Anonymous Method
Delegate是同样的。

接下去大家通过Lambda Expression达成位置的效益。

三、 Lambda
Expression

上面是透过兰姆da Expression达成地方相同效果的Code:

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

作者们因而Reflector分析编写翻译生成的Assembly,大家发掘它和通过Anonymous Method
Delegate落成的完全同样:Program Class,大家开掘它多了多个附加的Static成员,它们的名称都完全等同:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。

美高梅开户网址 152

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

美高梅开户网址 153[CompilerGenerated]

美高梅开户网址 154private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

美高梅开户网址 155

美高梅开户网址 156[CompilerGenerated]

美高梅开户网址 157private static bool <Main>b__0(int args)

美高梅开户网址 158美高梅开户网址 159美高梅开户网址 160{

美高梅开户网址 161    return (args > 0);

美高梅开户网址 162}

美高梅开户网址 163

我们越发来看望Main Method的IL。
 

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

和方面通过

Anonymous Method Delegate落成的时候完全是平等的。

四、Conclusion 

 

现行反革命我们得以得出结论了,Lambda
Expression本质上是多少个Anonymous Method
Delegate,那些Delegate的佚名性仅仅针对Programming
language来讲,编写翻译器会为它生成一个Named
delegate和1个它指向的Method。那一个三个额外生成的目标作为利用Anonymous
Method Delegate对应的Class的Static Method而存在。从实质上讲和一般的Delegate并不曾本质的分别。所以地方大家分别通过Named
delegate、Anonymous method
delegate和Lambda
Expression落成的1个办法是同等的。

C# 三.x相关内容:
[原创]深深驾驭C#
三.x的新特色(1):Anonymous
Type
[原创]深刻精通C#
3.x的新特征(二):Extension Method – Part
I
[原创]深深驾驭C#
3.x的新特色(2):Extension Method – Part
II
[原创]深远领会C# 叁.x的新特点(三):从Delegate、Anonymous
Method到拉姆da
Expression
[原创]深刻通晓C# 三.x的新特征(4):Automatically Implemented
Property
[原创]深深理解C# 三.x的新特色(伍):Object Initializer 和 Collection
Initializer

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图