AIR Native Extension for iOS 接抱第三在sdk 如何兑现 AppDelegate 生命周期

打通Android、IOS、ANE制作流程 – 知其然知其所以然 – 博客频道 –
CSDN.NET
 

起名 1class Program
起名 2起名 3    起名 4{
起名 5        static void Main()
起名 6起名 7        起名 8{
起名 9起名 10            var names = new List<string> 起名 11{ “Tom Cruise”, “Tom Hanks”, “Al Pacino”, “Harrison Ford” };
起名 12起名 13            var result = names.When(delegate(string name) 起名 14{ return name.StartsWith(“Tom”); });
起名 15            foreach (var name in result)
起名 16起名 17            起名 18{
起名 19                Console.WriteLine(name);
起名 20            }
起名 21        }
起名 22}
起名 23

1 FREObject initSDK(FREContext ctx, void *data, uint32_t argc, FREObject argv[])
2 {
3     id delegate = [UIApplication sharedApplication].delegate;
4     NSLog(@"------------delegate %@", delegate);
5 }

咱俩来看望通过Compiler举行编译生成的IL:

 

起名 24[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
起名 25public sealed class ExtensionAttribute : Attribute
起名 26起名 27起名 28{
起名 29}
起名 30

 

于LINQ,有一个可怜关键之风味:Deferred
伊娃(Eva)luation。在精通之特点此前,我们来拘禁一个事例:

二〇一八年交二零一九年举办了几乎只 iOS上之 AIR Native Extension (简称 ANE),
痛苦不堪。  ANE 的开发情势早已为长辈吐槽多多 效能低下 浪费生命
严重低于kpi 。体验了Unity的插件开发, 相相比较之下真的是喜上眉梢多矣,功效飙升。

与下的定义是一模一样的

随后自己拿引用那首作品展开教学

唯独,System.Runtime.CompilerService(Service)s.ExtensionAttribute和此外Custom
Attribute不同等,因为其是为了Extension
Method的使定义之,我们只好通过添加this Key word的语法来定义Extension
Method。所以当大家将System.Runtime.Compiler瑟维斯(Service)s.ExtensionAttribute直接下到Adds方法会并发下边的Compile
Error:

以xcode 中 新建一个 objective-c 文件 取名也 HookUtil  , xocde
将颇成一个HookUtil.m文件 将文件里之代码删干净,
复制上面的代码粘贴进去。但下的代码并无可以迎刃而解问题,真正使知其所以然依然要始终不渝不懈看罢自家末了是怎么化解之。

起名 31class Program
起名 32起名 33    起名 34{
起名 35        static void Main(string[] args)
起名 36起名 37        起名 38{
起名 39起名 40 var v = new Vector 起名 41{ X = 1, Y = 2 };
起名 42           v = v.Adds(v);
起名 43        }
起名 44}
起名 45

   

俺们由此上边的Code,从平密密麻麻的姓名列表中(”Tom Cruise”, “Tom Hanks”, “Al
Pacino”, “哈Rhyson Ford”)筛选名字(First Name)为Tom的人名。通过Where
Operator,传入一个盖Lambda Expression表示的罗标准(name =>
name.StartsWith(“Tom”))。
Where Operator就是通过Extension
Method的办法定义之。

有关这HookUtils做几触及表达: 

HookUtils凡IOS的Hook机制的实现,所以适用于拥有IOS的支出,这里只是针对Air应用做了片甩卖。 

Hook编制中得取使用之落实了生命周期的类名,这样才可以Hook处理,假如您是Xcode工程开发之代码这尔会很方便之找到这类名,这适用于IOS原生,Unity以及Cocos引擎,因为它们还会师下Xcode开发工具。但是,Air开发是于Flash
Builder上,并无直接关系到Xcode工程,通过代码打印Air应用的生命周期类,找到了Air的类名CTAppDelegate,于是代码中装置为,其他发动机自行修改,当然,你吧足以通过部署文件(Info.plist)获取,这样代码就无欲改了

 Class oldClass = objc_getClass([@"CTAppDelegate" UTF8String]);


你要在hooked**方中落实公的求实代码,最终当+ (void)load()计吃调用头文件定义之主意(void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL;来达到Hook的目的

及时段长的IL代码很肯定,就是当Adds方法及添加一个Customer
Attribute:System.Runtime.CompilerServices.ExtensionAttribute。ExtensionAttribute具有如下的概念:

作者:Panda Fang

出处:http://www.cnblogs.com/lonkiss/p/6492385.html

原创随笔,转载请注脚作者及出处,未经同意不可用于生意营利活动

起名 46.method public hidebysig static class Artech.ExtensionMethod.Vector 
起名 47Adds(class Artech.ExtensionMethod.Vector v,
起名 48class Artech.ExtensionMethod.Vector v1) cil managed
起名 49起名 50起名 51{
起名 52  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) 
起名 53  // Code size       53 (0x35)
起名 54  .maxstack  3
起名 55  .locals init ([0] class Artech.ExtensionMethod.Vector ‘<>g__起名,initLocal0’,
起名 56           [1] class Artech.ExtensionMethod.Vector CS$1$0000)
起名 57  IL_0000:  nop
起名 58  IL_0001:  newobj     instance void Artech.ExtensionMethod.Vector::.ctor()
起名 59  IL_0006:  stloc.0
起名 60  IL_0007:  ldloc.0
起名 61  IL_0008:  ldarg.0
起名 62  IL_0009:  callvirt   instance float64 Artech.ExtensionMethod.Vector::get_X()
起名 63  IL_000e:  ldarg.1
起名 64  IL_000f:  callvirt   instance float64 Artech.ExtensionMethod.Vector::get_X()
起名 65  IL_0014:  add
起名 66  IL_0015:  callvirt   instance void Artech.ExtensionMethod.Vector::set_X(float64)
起名 67  IL_001a:  nop
起名 68  IL_001b:  ldloc.0
起名 69  IL_001c:  ldarg.0
起名 70  IL_001d:  callvirt   instance float64 Artech.ExtensionMethod.Vector::get_Y()
起名 71  IL_0022:  ldarg.1
起名 72  IL_0023:  callvirt   instance float64 Artech.ExtensionMethod.Vector::get_Y()
起名 73  IL_0028:  add
起名 74  IL_0029:  callvirt   instance void Artech.ExtensionMethod.Vector::set_Y(float64)
起名 75  IL_002e:  nop
起名 76  IL_002f:  ldloc.0
起名 77  IL_0030:  stloc.1
起名 78  IL_0031:  br.s       IL_0033
起名 79  IL_0033:  ldloc.1
起名 80  IL_0034:  ret
起名 81} // end of method Extension::Adds
起名 82

地点是引用那篇博客的,我加好代码后即问题了, 这哪来调整用其也。
问了暴发经历的iOS开发者才知 其实并无用在其余函数里面来调用这多少个HookUtil里之函数,
这些仿佛格局 load就是进口, 只要申明也接近形式并于名叫load会被网自动调用。
制作好ane
后在demo中测试,原本可走起的demo自从加了HookUtil反而启动就闪退了,通过观察log发现
hookMethod执行了,果然是系自动调用这些代码, ane
还从未当demo中经按钮触发实例化呢

点我们相比较了Extension Method本身IL和一般Static Method
IL,现在我们看看当我们为Instance Method模式调用Extension
Method的IL。假使我们通过下的艺术调用Adds。 

遂加log 最终稳定及以34举办  assert(oldMethod);  这行挂掉,原来
oldMethod是null ,不过看半龙无看出来何地错了, 后来怀疑25行  oldClass   会不谋面吗是null 呢,
于是加了日记  NSLog(@”oldclass
%@”, oldClass);  果然
也是null , 这上想起这篇博客,也许不是CTAppDelegate 这么些名字也?
这篇博客说通过代码打印Air应用的生命周期类,找到了Air的类名CTAppDelegate。
于是当 hookMethod里面打印  

起名 83IL_002b:  call class Artech.ExtensionMethod.Vector Artech.ExtensionMethod.Extension::Adds(class Artech.ExtensionMethod.Vector,
起名 84class Artech.ExtensionMethod.Vector)
起名 85

言归正传, 痛苦之一即是难以实现AppDelegate
生命周期。关于生命周期实现,其实Android上的 ane 也难以入手。下次重写。假诺当
xcode上做一个正式的 iOS App 写 AppDelegate 很便利, 填函数就实施了。
可是于ANE上 没有透露这一个api给你实现。air 本身是运作于ios上之app ,adobe
实现它的下自己行使了 delegate 不过可休表露被大家利用。 我们选取adobe
air sdk做看重adobe 的框架, 束手束脚, 真的忍不住一边开一方面骂adobe
。既然adobe air用了 那么我们就是会因hook了, 下边那篇稿子非常值得看

起名 86        public IEnumerator<TSource> GetEnumerator()
起名 87起名 88        起名 89{
起名 90            return new WhenEnumerator<TSource>(this._source, this._predicate);
起名 91        }
起名 92

 

输出结果:

而要null ,然后以想啊, 会不相会是机太早啊。 于是置身了
ane的一个api方法中在 应用层demo中经过按钮触发,

运作程序,你会晤发觉少单foreach loop显示的结果依旧平的:Tom汉克(Hank)s。为什么result1事实上第一独Element被改变从前重回的,但我们最终输出的结果却反映的是移之后的数据源。通过我们地点的定义,你丰裕轻得答案。在此地自己若说的凡LINQ的一个重大之特色Deferred
伊娃(Eva)luation:在调用Operator的时刻并无会师出任何的别数据得到的长河,这些等级的天职是创造一个同于获取数据的表明式。只要你确实所用到是数目的上,接纳重数据源中经过你构建的表达式通过询问获取数据。

果不再是null 了, 打印出来的讳吧不是CTAppDelegate,而是 CTAppController
我之 airsdk 是21 ,adobe adobe 又变更名字了。  把25尽代码中的CTAppDelegate
改化 CTAppController 之后测试, delegate中的函数得到正确调用,
实现生命周期delegate就以此解决

对此另外一个Interface
IEnumerator<TSource>,直接调用数据源的Enumerator的同名方法实现了Current,和Reset()。对于MoveNext()即使经过如下的办法贯彻:把目前之职务设置于产一个饱筛选标准的Element上

1    id delegate = [UIApplication sharedApplication].delegate;
2     NSLog(@"delegate %@", delegate);

五、一个总体的Extension Method的山姆(Sam)ple

  1 //
  2 //  HookUtils.m
  3 //  ResearchMethodSwizzl
  4 //
  5 //  Created by 薛旻 on 15/4/27.
  6 //  Copyright (c) 2015年 薛旻. All rights reserved.
  7 //
  8 
  9 #import <Foundation/Foundation.h>
 10 #import <UIKit/UIKit.h>
 11 #import <objc/runtime.h>
 12 
 13 
 14 @interface HookUtils : NSObject
 15 
 16 + (void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL;
 17 
 18 @end
 19 
 20 @implementation HookUtils
 21 
 22 + (void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL {
 23     NSLog(@"hookMehod");
 24 
 25     Class oldClass = objc_getClass([@"CTAppDelegate" UTF8String]);
 26 
 27     Class newClass = [HookUtils class];
 28 
 29     //把方法加给原Class
 30     class_addMethod(oldClass, newSEL, class_getMethodImplementation(newClass, newSEL), nil);
 31     class_addMethod(oldClass, oldSEL, class_getMethodImplementation(newClass, defaultSEL),nil);
 32 
 33     Method oldMethod = class_getInstanceMethod(oldClass, oldSEL);
 34     assert(oldMethod);
 35     Method newMethod = class_getInstanceMethod(oldClass, newSEL);
 36     assert(newMethod);
 37     method_exchangeImplementations(oldMethod, newMethod);
 38 
 39 }
 40 
 41 + (void)load {
 42     NSLog(@"load");
 43     [self hookMehod:@selector(application:didFinishLaunchingWithOptions:) andDef:@selector(defaultApplication:didFinishLaunchingWithOptions:) andNew:@selector(hookedApplication:didFinishLaunchingWithOptions:)];
 44 
 45     [self hookMehod:@selector(applicationWillEnterForeground:) andDef:@selector(defaultApplicationWillEnterForeground:) andNew:@selector(hookedApplicationWillEnterForeground:)];
 46 }
 47 
 48 
 49 /*具体要走的代码*/
 50 -(BOOL)hookedApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic
 51 {
 52     NSLog(@"applicationDidFinishLaunching");
 53     [self hookedApplication:application didFinishLaunchingWithOptions:dic];
 54     return YES;
 55 }
 56 
 57 - (void)hookedApplicationWillResignActive:(UIApplication *)application {
 58     [self hookedApplicationWillResignActive:application];
 59 }
 60 
 61 - (void)hookedApplicationDidEnterBackground:(UIApplication *)application {
 62     [self hookedApplicationDidEnterBackground:application];
 63 }
 64 
 65 - (void)hookedApplicationWillEnterForeground:(UIApplication *)application {
 66     [self hookedApplicationWillEnterForeground:application];
 67 }
 68 
 69 - (void)hookedApplicationDidBecomeActive:(UIApplication *)application {
 70     [self hookedApplicationDidBecomeActive:application];
 71 }
 72 
 73 - (void)hookedApplicationWillTerminate:(UIApplication *)application {
 74     [self hookedApplicationWillTerminate:application];
 75 }
 76 
 77 /*支付宝对应的方法*/
 78 - (BOOL)hookedApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
 79     [self hookedApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];
 80     return YES;
 81 }
 82 
 83 
 84 
 85 -(BOOL)hookedApplication:(UIApplication*)application handleOpenURL:(NSURL*)url {
 86     [self hookedApplication:application handleOpenURL:url];
 87     return YES;
 88 }
 89 
 90 
 91 #pragma 默认
 92 /*default 默认不需要改动*/
 93 - (BOOL)defaultApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic { return YES;
 94 }
 95 
 96 - (void)defaultApplicationWillResignActive:(UIApplication *)application {}
 97 
 98 - (void)defaultApplicationDidEnterBackground:(UIApplication *)application {}
 99 
100 - (void)defaultApplicationWillEnterForeground:(UIApplication *)application {}
101 
102 - (void)defaultApplicationDidBecomeActive:(UIApplication *)application {}
103 
104 - (void)defaultApplicationWillTerminate:(UIApplication *)application {}
105 
106 - (BOOL)defaultApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
107     return YES;
108 }
109 
110 - (BOOL)defaultApplication:(UIApplication *)application handleOpenURL:(NSURL *)url {
111     return YES;
112 }
113 @end

由此比,我们发现及方面定义之一般的Static
Method生成的IL唯一的分别就是是:在Adds方法定义最最先补充加了下面一段落代码:

起名 93Do not use ‘System.Runtime.CompilerServices.ExtensionAttribute’. Use the ‘this’ keyword instead.

对于得IL如下:

咱俩也可因而Lambda Expression的法子来以When Operator:

据此下边Extension Method的定义

下面是Main Method的IL:

C# 3.x相关内容:
[原创]深入领会C#
3.x的新特性(1):Anonymous
Type

[原创]深深了然C#
3.x的初特点(2):Extension Method – Part
I

[原创]深切领悟C#
3.x的初特色(2):Extension Method – Part
II

[原创]深入了解C# 3.x的新特性(3):从Delegate、Anonymous
Method到兰姆da
Expression

[原创]深刻明白C# 3.x的初特点(4):Automatically Implemented
Property

[原创]深深明白C# 3.x的新特征(5):Object Initializer 和 Collection
Initializer

顶本结,这么些新的LINQ Operator被创立,现在我们可遵照使用Where
operator的计来调用When。

Deferred Evaluation

和C# 3.0底另新特色相似,Extension Method仅仅是C#这种.NET Programming
Language的初特点而已。大家领会,C#凡一样栽典型的编译型的语言,大家编辑的Source
Code必须先行通过同C# Compiler编译成Assembly,才能够叫CLR加载,被JIT
编译成Machine Instruction并最后让实施。C#
3.0的这一个新的风味大都影响Source被C#
Compiler编译成Assembly这多少个等级,换句话说,那些新特仅仅是Compiler的初特色而已。通过对Compiler举行更正,促使他将C#
3.0引入的新的语法编译成相对应的IL Code,从精神上看,这个IL Code
和原的IL并没本质的分。所有当让编译生成成Assembly被CLR加载、执行的时刻,CLR是发现不顶这多少个新的风味的。

自Extension Method的概念我们而观察,Extension Method本质上是一个Static
Method。不过咱累因为Instance Method的模式展开调用。C#
Compiler的效用好明朗:管一个因为Instance Method格局调用的Source
Code编译成的吃对诺让人情的Static Method调用的IL Code

以下3个成员分头表示:用于实践筛选的数据源、用于判断是否满足筛选标准的断言和数据源的Enumerator对象。

起名 94起名 95var names = new List<string> 起名 96{ “Tom Cruise”, “Tom Hanks”, “Al Pacino”, “Harrison Ford” };
起名 97var result = names.Where(name => name.StartsWith(“Tom”));
起名 98foreach(var name in result)
起名 99起名 100起名 101{
起名 102      Console.WriteLine(name);
起名 103}
起名 104

public static Vector Adds(Vector v, Vector v1)
{
  return new Vector { X = v.X + v1.X, Y = v.Y + v1.Y };
}

我们还来探望对于经过下边的不二法门定义之Extension Method:

四、Extension Method的本质

起名 105static void Main()
起名 106起名 107起名 108{
起名 109起名 110            var names = new List<string> 起名 111{ “Tom Cruise”, “Tom Hanks”, “Al Pacino”, “Harrison Ford” };
起名 112            var result1 = names.When(name=>name.StartsWith(“Tom”));
起名 113            names[0] = “Stephen Chou”;
起名 114            var result2 = names.When(name => name.StartsWith(“Tom”));
起名 115
起名 116
起名 117            foreach (var name in result1)
起名 118起名 119            起名 120{
起名 121                Console.WriteLine(name);
起名 122            }
起名 123
起名 124            foreach (var name in result2)
起名 125起名 126            起名 127{
起名 128                Console.WriteLine(name);
起名 129            }
起名 130}
起名 131

虽然Extension Method本质上只是一个Static Class的Static
Method成员,不过到底与习俗的Static
Method有所不同:在首先独Parameter前加了一个this重在字。大家本来瞧她们中的微薄的区别。我们先行定义一个一般的Static
Method:

起名 132public bool MoveNext()
起名 133起名 134        起名 135{
起名 136            if (!this._sourceEnumerator.MoveNext())
起名 137起名 138            起名 139{
起名 140                return false;
起名 141            }
起名 142
起名 143            while (!this._predicate(this._sourceEnumerator.Current))
起名 144起名 145            起名 146{
起名 147                if (!this._sourceEnumerator.MoveNext())
起名 148起名 149                起名 150{
起名 151                    return false;
起名 152                }
起名 153            }
起名 154
起名 155            return true;
起名 156        }
起名 157

对了然IL的人头吧,对点的IL code应该很轻通晓。

透过地方一样节约之牵线,我们知晓了当C#被哪些错过定义一个Extension
Method:它是概念在一个Static
class
中的、第一个Parameter标记为this根本字的Static
Method
。在当时无异于省中,我们来更是认识Extension Method。

起名 158private IEnumerable<TSource> _source;
起名 159private Function<TSource, bool> _predicate;
起名 160private IEnumerator<TSource> _sourceEnumerator;
起名 161

大家得经Delegate的法来接纳When Operator:

起名 162[ExtensionAttribute]
起名 163public static Vector Adds(Vector v, Vector v1) 
起名 164起名 165起名 166{
起名 167起名 168            return new Vector 起名 169{ X = v.X + v1.X, Y = v.Y + v1.Y };
起名 170}
起名 171

起名 172public static Vector Adds(this Vector v, Vector v1)
起名 173起名 174起名 175{
起名 176起名 177            return new Vector 起名 178{ X = v.X + v1.X, Y = v.Y + v1.Y };
起名 179}
起名 180

起名 181.custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) 

经对IL的剖析,我们基本上看到了Extension
Method的本色。我们更来大概描述一下针对Compiler的编译过程:当Compiler对Adds方法的调用举行编译的进程的时,它要认清是Adds格局是Vector
Type的成员
还是以Extension Method的主意定义。Extension
Method的先期级是低的,只有确定Vector中从不定义相应的Adds方法的时光,Compiler才会在援的Namespace中查阅这几个Namespace中是否定义有对应之Adds
Extension Method的Static
Class。找到后作举办对应的编译,否则出现编译错误。

起名 182static void Main()
起名 183起名 184        起名 185{
起名 186起名 187            var names = new List<string> 起名 188{ “Tom Cruise”, “Tom Hanks”, “Al Pacino”, “Harrison Ford” };
起名 189            var result = names.When(name=>name.StartsWith(“Tom”));
起名 190            foreach (var name in result)
起名 191起名 192            起名 193{
起名 194                Console.WriteLine(name);
起名 195            }
起名 196        }
起名 197

C# 3.0也LINQ定义了同样名目繁多的Operator:select, from,where,orderby…,
促使我们按OO的主意来拍卖千头万绪的数量,比如XML,Relational DB
Data,C#中IEnumeratable<T> Object。比如:

经过地方的IL,大家来看调用的凡Artech.ExtensionMethod.Extension的Adds方法。

WhenEnumerator的定义是实现When Extension
Method的重中之重,大家前天着重来介绍她的现实性实现。WhenEnumerator实现了Interface
Enumerable<T>,
为了简单,我们呢它对应的Enumerator的实现吗定义在同一个Class中,所以WhenEnumerator实现了有限独Interface:IEnumerable<TSource>,
IEnumerator<TSource>。
 

在此地提供的山姆ple就是概念一个成功Where
Operator相同效果的Operator,大家管这Operator起名叫吧When

起名 198public delegate TResult Function<Tparam, TResult>(Tparam param);

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       50 (0x32)
  .maxstack  2
  .locals init ([0] class Artech.ExtensionMethod.Vector v,
           [1] class Artech.ExtensionMethod.Vector ‘<>g__initLocal0’)
  IL_0000:  nop
  IL_0001:  newobj     instance void Artech.ExtensionMethod.Vector::.ctor()
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldc.r8     1.
  IL_0011:  callvirt   instance void Artech.ExtensionMethod.Vector::set_X(float64)
  IL_0016:  nop
  IL_0017:  ldloc.1
  IL_0018:  ldc.r8     2.
  IL_0021:  callvirt   instance void Artech.ExtensionMethod.Vector::set_Y(float64)
  IL_0026:  nop
  IL_0027:  ldloc.1
  IL_0028:  stloc.0
  IL_0029:  ldloc.0
  IL_002a:  ldloc.0
  IL_002b:  call       class Artech.ExtensionMethod.Vector Artech.ExtensionMethod.Extension::Adds(class Artech.ExtensionMethod.Vector,
class Artech.ExtensionMethod.Vector)
  IL_0030:  stloc.0
  IL_0031:  ret
} // end of method Program::Main

随即以Static Class Extesnion中定义了Extension
Method:When。该办法包含两独参数,其中一个凡是举办筛选的数据源,另一个是用以判断数据源每个对象是不是满意你所定义的罗标准的断言。重返一个大家从定义之、实现了IEnumerable的WhenEnumerator对象。

起名 199.method private hidebysig static void  Main(string[] args) cil managed
起名 200起名 201起名 202{
起名 203  .entrypoint
起名 204  // Code size       50 (0x32)
起名 205  .maxstack  2
起名 206  .locals init ([0] class Artech.ExtensionMethod.Vector v,
起名 207           [1] class Artech.ExtensionMethod.Vector ‘<>g__initLocal0’)
起名 208  IL_0000:  nop
起名 209  IL_0001:  newobj     instance void Artech.ExtensionMethod.Vector::.ctor()
起名 210  IL_0006:  stloc.1
起名 211  IL_0007:  ldloc.1
起名 212  IL_0008:  ldc.r8     1.
起名 213  IL_0011:  callvirt   instance void Artech.ExtensionMethod.Vector::set_X(float64)
起名 214  IL_0016:  nop
起名 215  IL_0017:  ldloc.1
起名 216  IL_0018:  ldc.r8     2.
起名 217  IL_0021:  callvirt   instance void Artech.ExtensionMethod.Vector::set_Y(float64)
起名 218  IL_0026:  nop
起名 219  IL_0027:  ldloc.1
起名 220  IL_0028:  stloc.0
起名 221  IL_0029:  ldloc.0
起名 222  IL_002a:  ldloc.0
起名 223  IL_002b:  call       class Artech.ExtensionMethod.Vector Artech.ExtensionMethod.Extension::Adds(class Artech.ExtensionMethod.Vector,
起名 224class Artech.ExtensionMethod.Vector)
起名 225  IL_0030:  stloc.0
起名 226  IL_0031:  ret
起名 227} // end of method Program::Main
起名 228

通过再次来到一个WhenEnumerator对象,实现了IEnumerable<TSource>的GetEnumerator()方法。 

起名 229Tom Cruise
起名 230Tom Hanks
起名 231

起名 232public static class Extension
起名 233起名 234    起名 235{
起名 236        public static IEnumerable<TSource> When<TSource>(this IEnumerable<TSource> source, Function<TSource, bool> predicate)
起名 237起名 238        起名 239{
起名 240            return new WhenEnumerator<TSource>(source, predicate);
起名 241        } 
起名 242    }
起名 243

注:Vector的定义参见《深深领悟C# 3.0之初特点(2):Extension Method –
Part
I
》。

起名 244public static class Extension
起名 245起名 246    起名 247{
起名 248         public static Vector Adds(this Vector v, Vector v1)
起名 249起名 250        起名 251{
起名 252起名 253            return new Vector 起名 254{ X = v.X + v1.X, Y = v.Y + v1.Y };
起名 255        }
起名 256}
起名 257

起名 258using System;
起名 259using System.Collections.Generic;
起名 260using System.Linq;
起名 261using System.Text;
起名 262using System.Collections;
起名 263
起名 264namespace Artech.ExtensionMethod
起名 265起名 266起名 267{
起名 268    public delegate TResult Function<Tparam, TResult>(Tparam param);
起名 269
起名 270    public static class Extension
起名 271起名 272    起名 273{
起名 274        public static IEnumerable<TSource> When<TSource>(this IEnumerable<TSource> source, Function<TSource, bool> predicate)
起名 275起名 276        起名 277{
起名 278            return new WhenEnumerator<TSource>(source, predicate);
起名 279        }  
起名 280
起名 281    }
起名 282
起名 283    public class WhenEnumerator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
起名 284起名 285    起名 286{
起名 287        private IEnumerable<TSource> _source;
起名 288        private Function<TSource, bool> _predicate;
起名 289        private IEnumerator<TSource> _sourceEnumerator;
起名 290
起名 291        public WhenEnumerator(IEnumerable<TSource> source, Function<TSource, bool> predicate)
起名 292起名 293        起名 294{
起名 295            this._source = source;
起名 296            this._predicate = predicate;
起名 297            this._sourceEnumerator = this._source.GetEnumerator();
起名 298        }
起名 299
起名 300起名 301        IEnumerable Members#region IEnumerable<TSource> Members
起名 302
起名 303        public IEnumerator<TSource> GetEnumerator()
起名 304起名 305        起名 306{
起名 307            return new WhenEnumerator<TSource>(this._source, this._predicate);
起名 308        }
起名 309
起名 310        #endregion
起名 311
起名 312起名 313        IEnumerable Members#region IEnumerable Members
起名 314
起名 315        IEnumerator IEnumerable.GetEnumerator()
起名 316起名 317        起名 318{
起名 319            throw new Exception(“The method or operation is not implemented.”);
起名 320        }
起名 321
起名 322        #endregion
起名 323
起名 324起名 325        IEnumerator Members#region IEnumerator<TSource> Members
起名 326
起名 327        public TSource Current
起名 328起名 329        起名 330{
起名 331起名 332            get 起名 333{ return this._sourceEnumerator.Current; }
起名 334        }
起名 335
起名 336        #endregion
起名 337
起名 338起名 339        IDisposable Members#region IDisposable Members
起名 340
起名 341        public void Dispose()
起名 342起名 343        起名 344{
起名 345            //throw new Exception(“The method or operation is not implemented.”);
起名 346        }
起名 347
起名 348        #endregion
起名 349
起名 350起名 351        IEnumerator Members#region IEnumerator Members
起名 352
起名 353        object IEnumerator.Current
起名 354起名 355        起名 356{
起名 357            get
起名 358起名 359            起名 360{
起名 361                return this._sourceEnumerator.Current;
起名 362            }
起名 363        }
起名 364
起名 365        public bool MoveNext()
起名 366起名 367        起名 368{
起名 369            if (!this._sourceEnumerator.MoveNext())
起名 370起名 371            起名 372{
起名 373                return false;
起名 374            }
起名 375
起名 376            while (!this._predicate(this._sourceEnumerator.Current))
起名 377起名 378            起名 379{
起名 380                if (!this._sourceEnumerator.MoveNext())
起名 381起名 382                起名 383{
起名 384                    return false;
起名 385                }
起名 386            }
起名 387
起名 388            return true;
起名 389        }
起名 390
起名 391        public void Reset()
起名 392起名 393        起名 394{
起名 395            this._sourceEnumerator.Reset();
起名 396        }
起名 397
起名 398        #endregion
起名 399    }
起名 400}
起名 401

咱俩来探视我们新的LINQ Operator:When的概念。我首先定义了一个Generic
Delegate:Function。实际上他定义了一个一元函数y = f(x),TParam和TResult为参数和归值得类型。 

于介绍了Extension
Method的精神之后,我们通过一个相持完整的Sample进一步明白Extension
Method的运用,通过者山姆(Sam)ple,大家还可省略精晓LINQ的原理。

一目了然这种艺术再度简单。 

发表评论

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

网站地图xml地图