.NET 3.5擴(kuò)展方法點(diǎn)評(píng):優(yōu)點(diǎn)與問(wèn)題
.NET 3.5擴(kuò)展方法:新增的語(yǔ)言特性
原本,我聽(tīng)說(shuō) Partial Class 的時(shí)候,以為可以為已存在的類添加方法了,不過(guò),Partial Class 只能在同一個(gè) Assembly 之中的要求,使得它并不能實(shí)現(xiàn)這一點(diǎn)。.Net 3.5 增加了很多語(yǔ)言特性,擴(kuò)展方法是其中一個(gè)。用擴(kuò)展方法,我們就可以為已經(jīng)存在的類添加方法。
- public static class ExtendTest
- {
- public static Print(this object o)
- {
- Console.WriteLine(o);
- }
- }
之后,就可以對(duì)于任意的 object 使用這個(gè)方法:
- string s = "hello";
- s.Print();
- "X".Print();
- MyClass x = new MyClass();
- x.Print();
.NET 3.5擴(kuò)展方法的創(chuàng)建
對(duì)于擴(kuò)展方法的創(chuàng)建,基本上,只有兩點(diǎn)記住就可以了:必須是靜態(tài)方法,***個(gè)參數(shù)增加 this 關(guān)鍵字。
用 Reflector 查看了一下,和我的猜測(cè)基本一致,其實(shí)它的實(shí)現(xiàn)是使用的自定義屬性,所以擴(kuò)展方法基本上可以看成是編譯器特性:
- public static class ExtendTest
- {
- [ Extend ]
- public static Print(object o)
- {
- Console.WriteLine(o);
- }
- }
擴(kuò)展方法很好用,使用上確實(shí)可以和動(dòng)態(tài)語(yǔ)言像 Python、Ruby 之類的相比了。不過(guò),畢竟 C# 是靜態(tài)語(yǔ)言,擴(kuò)展方法還是有一些限制的。
.NET 3.5擴(kuò)展方法的限制
一個(gè)限制是:不能使用原有類的私有或保護(hù)成員。這個(gè)問(wèn)題,怎么說(shuō)呢,大部分情況下沒(méi)有問(wèn)題,不過(guò)如果真的想使用私有或保護(hù)成員的時(shí)候,會(huì)很頭疼。如果要給 .Net framework 中的類添加方法,這個(gè)問(wèn)題也許并不是太大吧,畢竟一般我們也只知道它們的公有成員。如果要給自己的 DLL 添加一個(gè)新的 DLL,也做到原有 DLL 用于 .Net 2.0,新 DLL 擴(kuò)展原 DLL 的話,比較會(huì)遇到。我在 DbEntry.Net 中對(duì)于這個(gè)問(wèn)題的解決方案是,使用友元程序集。這種方法還是需要修改原 DLL,添加新 DLL 為友元程序集,另外,將需要訪問(wèn)的成員標(biāo)注為 internal 才行。
另一個(gè)限制:不能給一個(gè)類添加靜態(tài)方法。不知道是不是我沒(méi)有找到,反正感覺(jué),本來(lái)就是靜態(tài)方法了,怎么才能再標(biāo)注為實(shí)現(xiàn)靜態(tài)方法呢?難道用 static static ?當(dāng)然,使用的場(chǎng)景應(yīng)該也不多吧。
再一個(gè)限制:不能給一個(gè)類添加接口。這個(gè)么,本來(lái)就不是擴(kuò)展方法的設(shè)計(jì)目標(biāo),而且,實(shí)現(xiàn)上似乎也會(huì)麻煩很多,所以本來(lái)不該抱怨,不過(guò),如果能實(shí)現(xiàn)的話,確實(shí)會(huì)有很多地方會(huì)很方便。比如,如果能給 DbObjectModel 添加 IQueryable 接口,就可以只通過(guò)增加一個(gè) using 而實(shí)現(xiàn)所有的 Linq 功能,而有這個(gè)限制的時(shí)候,只能再實(shí)現(xiàn)一個(gè) LinqDbObjectModel 之類的了……
我發(fā)現(xiàn)的,就這3個(gè)限制,其它方面,都實(shí)現(xiàn)的很好,IDE 提示也很舒服~
【編輯推薦】