本文介紹了.NET 3.5擴充方法的一些特性,建立方法,優點以及存在的一些限制。擴充方法很好用,使用上確實可以和動態語言像 Python、Ruby 之類的相比了。
.NET 3.5擴充方法:新增的語言特性
原本,我聽說 Partial Class 的時候,以為可以為已存在的類添加方法了,不過,Partial Class 只能在同一個 Assembly 之中的要求,使得它並不能實現這一點。.Net 3.5 增加了很多語言特性,擴充方法是其中一個。用擴充方法,我們就可以為已經存在的類添加方法。
- public static class ExtendTest
- {
- public static Print(this object o)
- {
- Console.WriteLine(o);
- }
- }
之後,就可以對於任意的 object 使用這個方法:
- string s = "hello";
- s.Print();
- "X".Print();
- MyClass x = new MyClass();
- x.Print();
.NET 3.5擴充方法的建立
對於擴充方法的建立,基本上,只有兩點記住就可以了:必須是靜態方法,第一個參數增加 this 關鍵字。
用 Reflector 查看了一下,和我的猜測基本一致,其實它的實現是使用的自訂屬性,所以擴充方法基本上可以看成是編譯器特性:
- public static class ExtendTest
- {
- [ Extend ]
- public static Print(object o)
- {
- Console.WriteLine(o);
- }
- }
擴充方法很好用,使用上確實可以和動態語言像 Python、Ruby 之類的相比了。不過,畢竟 C# 是靜態語言,擴充方法還是有一些限制的。
.NET 3.5擴充方法的限制
一個限制是:不能使用原有類的私人或保護成員。這個問題,怎麼說呢,大部分情況下沒有問題,不過如果真的想使用私人或保護成員的時候,會很頭疼。如果要給 .Net framework 中的類添加方法,這個問題也許並不是太大吧,畢竟一般我們也只知道它們的公有成員。如果要給自己的 DLL 添加一個新的 DLL,也做到原有 DLL 用於 .Net 2.0,新 DLL 擴充原 DLL 的話,比較會遇到。我在 DbEntry.Net 中對於這個問題的解決方案是,使用friend 組件。這種方法還是需要修改原 DLL,添加新 DLL
為friend 組件,另外,將需要訪問的成員標註為 internal 才行。
另一個限制:不能給一個類添加靜態方法。不知道是不是我沒有找到,反正感覺,本來就是靜態方法了,怎麼才能再標註為實現靜態方法呢?難道用 static static ?當然,使用的情境應該也不多吧。
再一個限制:不能給一個類添加介面。這個麼,本來就不是擴充方法的設計目標,而且,實現上似乎也會麻煩很多,所以本來不該抱怨,不過,如果能實現的話,確實會有很多地方會很方便。比如,如果能給 DbObjectModel 添加 IQueryable 介面,就可以只通過增加一個 using 而實現所有的 Linq 功能,而有這個限制的時候,只能再實現一個 LinqDbObjectModel 之類的了……
我發現的,就這3個限制,其它方面,都實現的很好,IDE 提示也很舒服~
出處: http://developer.51cto.com/art/200908/143041.htm