在上一篇博文當中,我們例舉了一個機房自動化系統的邏輯控制程序,其中用到了Lambda表達式,因此方便了我們程序功能的實現.然而,我們不能僅僅為實現功能,完成任務而奮斗,應該知其然,知其所以然,也就是說,知道了Lambda表達式能夠帶來這樣的方便,也應該知道為什麼能夠帶來這樣的方便,接下來,就跟大家一起來一次小小的探索之旅吧.
為了弄清為什麼,我們用Reflector反編譯一下源程序,
?
static void Main(string[] args)
{
Monitor.OpenEventHandler OnOpen;//定義一個委托變量
OpenSomething openSomething = new OpenSomething();//實例化用於開啟的對象
OnOpen = openSomething.OpenPower;
OnOpen += openSomething.OpenServer;
OnOpen += () => openSomething.OpenServices(5);//依然是把方法的引用賦值給委托變量
OnOpen();
Console.ReadKey();
}
}
用Reflector反編譯一下,查看Program類的Main方法,如下圖
先是實例化一個OpenSomething對象,然後實例化OpenEventHandler類型的委托變量,並將OpenPower方法的引用賦給它,這在源程序中是分兩行來完成的,這裡因為是反編譯,其實道理都一樣.
接下來的一行代碼,揭示了給委托賦值的原理,也就是我們用的”+=”符號,在反編譯之後,可以看到,它其實是調用了Delegate類的Combine方法,該方法的作用是把兩個委托連接起來,它有兩個參數,參數類型都是委托,第一個是OnOpen,也就是原委托,第二個就是需要連接的另一個委托,new Monitor.OpenEventHandler(openSomething.OpenPower)其實是實例化了一個新的委托變量,並以此來和OnOpen連接。因此,我們得知,在日常使用”+=”時,表面上看起來是將方法名”拼接”到一個委托變量的後面,調用委托時,會依次調用這些方法,而實際上是將兩個類型相同的委托變量Combine到一起,原來如此啊……
再接再勵,下面的一行代碼對應源程序中的Lambda表達式了,它與上一行不同的是,第二個參數用到了delegate{…}語法,這是匿名委托,由此可見,在用Lambda表達式時,內部實現原理其實就是新定義了一個可以傳參的匿名委托,這樣,我們就明白了,連接類型相同的委托變量時,程序會實例化一個新委托變量,而連接不同類型的委托變量,程序會定義並實例化一個匿名委托,用於連接,而對於委托變量之間的連接,並不要求它們擁有相同的委托類型。
Lambda表達式在一定程度上對以前的技術進行了封裝,而至於為什麼要封裝,以及除封裝以外還有的許多其他特性,是值得我們去研究的。我們在學習對自己來說是新的技術的時候,要養成知其所以然的習慣,知道Lambda表達式可以這樣用,再經過類似本文這樣的探究之後,對它的印象是不是會更深刻呢。了解了它,再用它,才會得心應手,可控性才會強,出問題了,也更容易發現。這就好比在公司,老板要對他的員工委以重任,必須先要了解這個員工的性格,考慮他是否合適做,而不僅僅是看他能力,一樣的。
摘自 白光