Expression经验在此以前言,深远掌握C

By admin in 4858.com on 2019年4月6日

对于C#中的Expression天性想必从事C#支付的校友都不会不熟悉,网上和田园里都有不少的好的小说介绍。作者想也远非要求再去写1些稿子去介绍,科学普及或是从入门到明白之类的。

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

对于C#中的Expression脾气想必从事C#支出的同室都不会目生,网上和田园里都有许多的好的文章介绍。笔者想也未曾供给再去写1些稿子去介绍,科学普及或是从入门到明白之类的。

那再而叁串的小说主若是就兑现工作和读书进度中的一些思索、难点的缓解以及自觉有趣的觉察等作些分享。

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

例于开发WPF的同班们每一日要接触的ViewModel中,

OnPropertyChanged(() => Name);

要比

OnPropertyChanged("Name")

大雅。并且更多的功利是能够在编写翻译时检查错误,尤其是在Property名字被更改后。

 

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

Expression经验之壹:合并LambdaExpression

Expression经验之2:LambdaExpression变换

Expression经验之叁:LambdaExpression作缓存key

 

对于C#中的Expression特性想必从事C#开发的同班都不会素不相识,网上和田园里都有为数不少的好的稿子介绍。小编想…

对于C#中的Expression特性想必从事C#付出的校友都不会不熟悉,网上和田园里都有很多的好的篇章介绍。我想也尚无须求再去写壹些稿子去介绍,科学普及或是从入门到驾驭之类的。

较在此之前叁个本子,对于C# 3.x和VB 玖来说,LINQ是最具吸重力的。基本上很多的新的特色都以环绕着LINQ的兑现来规划的。借助Extension
Method,我们能够为LINQ定义一多元的Operator。通过拉姆da Expression我们得以为LINQ编写越发从简的查询。我们能够说那几个新的特征成就了LINQ,也能够说这一个新特性就是为着贯彻LINQ而发生,不过我们相应知道,对于那些新引入的特色,LINQ并非他们唯一的用武之地,在相似的编制程序中,大家也得以行使它们。

那体系的小说主即使就落到实处工作和读书进程中的1些考虑、难点的缓解以及自觉有趣的意识等作些分享。

这两次三番串的小说重假如就兑现工作和读书进度中的一些盘算、难点的缓解以及自觉有趣的意识等作些分享。

继上一章,介绍Expression经验在此以前言,深远掌握C。Extension
Method自此,大家随后来介绍另2个重要的特色:拉姆da
Expression。在前方的两篇小说中,小编频仍在强调那样的2个定义: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,我们先不直接来介绍拉姆da
Expression, 大家先来探视大家最为纯熟的Delegate的事例: 

要比

要比

4858.com 1using System;
4858.com 2using System.Collections.Generic;
4858.com 3using System.Linq;
4858.com 4using System.Text;
4858.com 5
4858.com 6namespace Artech.LambdaExpression
4858.com 74858.com 84858.com 9{
4858.com 10    class Program
4858.com 114858.com 12    4858.com 13{
4858.com 14        static void Main()
4858.com 154858.com 16        4858.com 17{
4858.com 18            _namedMethodDelegate = new Function<int, bool>(SomeMethod);
4858.com 19            Function<int, bool> function1 = _namedMethodDelegate;
4858.com 20            function1(20);     
4858.com 21
4858.com 22        }
4858.com 23        private static Function<int, bool> _4858.com,namedMethodDelegate;
4858.com 24
4858.com 25        private static bool SomeMethod(int args)
4858.com 264858.com 27        4858.com 28{
4858.com 29            return (args > 0);
4858.com 30        }
4858.com 31
4858.com 32    }
4858.com 33
4858.com 34    delegate TResult Function<TArgs, TResult>(TArgs args);
4858.com 35
4858.com 36}

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

上边的事例很不难,先定3个Generic Delegate :Function。在Program Class中定义1个Static的Function字段_namedMethodDelegate和与之相应的Method:SomeMethod,判断输入的数字是不是高于零。在Main中实例化_namedMethodDelegate,并调用它。

大雅。并且越多的裨益是足以在编写翻译时检查错误,越发是在Property名字被转移后。

淡雅。并且更多的好处是能够在编写翻译时检查错误,特别是在Property名字被转移后。

咱俩因而IL Disassembler那几个Utility来探望Main方法的IL代码。为了让对IL Instruction不是很领会的读者进一步便于地领会整个实施进程,作者加了简易注释。对于那几个愿意越来越理解任何MSIL
Instruction列表的读者,能够参考:MSIL Instruction
Table。

 

 

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

好了,对Expression的表彰就不多说了。以下是自作者想分享的阅历:

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

对于Delegate,俺无须再作深远的介绍,相信大家早就了如指掌。在那边要求重点提议是,下边介绍的内容将是再而三部分的基础,通过前面包车型客车对Anonymous
Method和拉姆da expression介绍,你会意识它们生成的代码结构和方面包车型地铁是丰富相像的。

Expression经验之一:合并兰姆daExpression

Expression经验之1:合并LambdaExpression

二、  Anonymous
Method Delegate

Expression经验之二:LambdaExpression变换

Expression经验之二:拉姆daExpression变换

Anonymous Method是C# ②.0引进的2个可怜好用的效果。通过Anonymous
Method,大家能够Delegate的贯彻直接以Inline的不2秘籍放入Delegate对象使用的职务,而无须再繁琐地创立多少个Delegate,并通过定义在某些Class中兼有相同表明的Method来事例化这些Delegate Instance,最后才将那几个delegate instance传入供给调用的Method。

 

 

笔者们未来透过Anonymous Method来简化上边的代码。

4858.com 60using System;
4858.com 61using System.Collections.Generic;
4858.com 62using System.Linq;
4858.com 63using System.Text;
4858.com 64
4858.com 65namespace Artech.LambdaExpression
4858.com 664858.com 674858.com 68{
4858.com 69    class Program
4858.com 704858.com 71    4858.com 72{
4858.com 73        static void Main()
4858.com 744858.com 75        4858.com 76{
4858.com 77            Function<int, bool> function2 = delegate(int args)
4858.com 784858.com 79            4858.com 80{
4858.com 81                return args > 0;
4858.com 82            };
4858.com 83            function2(20);   
4858.com 84        }
4858.com 85    }
4858.com 86    delegate TResult Function<TArgs, TResult>(TArgs args);
4858.com 87}
4858.com 88

大家经过Reflector分析编写翻译生成的Assembly,我们发现它抱有下边包车型客车布局。进一步分析Program
Class,我们发现它多了四个附加的Static成员:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。那是编写翻译器的功绩。

4858.com 89

上面分别是<>9__CachedAnonymousMethodDelegate1和<Main>b__0的定义:

4858.com 90[CompilerGenerated]

4858.com 91private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

4858.com 92[CompilerGenerated]

4858.com 93private static bool <Main>b__0(int args)

4858.com 944858.com 954858.com 96{

4858.com 97    return (args > 0);

4858.com 98}

4858.com 99

是还是不是本人大家位置1节定义的_namedMethodDelegate和SomeMethod这几个七个静态成员1致?  

大家越来越分析Main Method的IL。

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

和大家地点一节的IL比较,是不是出奇地相似。所用大家得以说,大家在率先节中Named
Delegate和Anonymous Method
Delegate是同1的。

接下去大家经过拉姆da Expression达成地点的意义。

三、 Lambda
Expression

上面是通过拉姆da Expression完结地点一样作用的Code:

4858.com 126using System;
4858.com 127using System.Collections.Generic;
4858.com 128using System.Linq;
4858.com 129using System.Text;
4858.com 130
4858.com 131namespace Artech.LambdaExpression
4858.com 1324858.com 1334858.com 134{
4858.com 135    class Program
4858.com 1364858.com 137    4858.com 138{
4858.com 139        static void Main()
4858.com 1404858.com 141        4858.com 142{
4858.com 143            Function<int, bool> function3 = x => x > 0;
4858.com 144            function3(20);
4858.com 145        }
4858.com 146    }
4858.com 147
4858.com 148    delegate TResult Function<TArgs, TResult>(TArgs args);
4858.com 149
4858.com 150}
4858.com 151

大家通过Reflector分析编写翻译生成的Assembly,大家发现它和经过Anonymous Method
Delegate实现的通通等同:Program Class,大家发现它多了多少个附加的Static成员,它们的称号都统统相同:<>9__CachedAnonymousMethodDelegate1和<Main>b__0。

4858.com 152

这两个Static Member:<>9__CachedAnonymousMethodDelegate1和<Main>b__0的定义也于大家透过Anonymous Method
Delegate完毕时一模壹样:

4858.com 153[CompilerGenerated]

4858.com 154private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

4858.com 155

4858.com 156[CompilerGenerated]

4858.com 157private static bool <Main>b__0(int args)

4858.com 1584858.com 1594858.com 160{

4858.com 161    return (args > 0);

4858.com 162}

4858.com 163

我们进一步来看望Main Method的IL。
 

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

和地点通过

Anonymous Method Delegate完结的时候完全是同一的。

四、Conclusion 

 

如今我们能够得出结论了,拉姆da
Expression本质上是贰个Anonymous Method
Delegate,那些Delegate的匿名性仅仅针对Programming
language而言,编译器会为它生成八个Named
delegate和3个它指向的Method。这么些三个额外生成的靶子作为利用Anonymous
Method Delegate对应的Class的Static Method而存在。从实质上讲和一般的Delegate并不曾精神的差异。所以地点大家分别通过Named
delegate、Anonymous method
delegate和Lambda
Expression达成的三个方法是1样的。

C# 三.x相关内容:
[原创]深切通晓C#
三.x的新天性(壹):Anonymous
Type
[原创]深切掌握C#
三.x的新性格(2):Extension Method – Part
I
[原创]深切驾驭C#
三.x的新个性(贰):Extension Method – Part
II
[原创]深入明白C# 3.x的新天性(叁):从Delegate、Anonymous
Method到Lambda
Expression
[原创]深远精通C# 三.x的新特色(四):Automatically Implemented
Property
[原创]深远明白C# 3.x的新特色(伍):Object Initializer 和 Collection
Initializer

发表评论

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

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有