今天我們接著看一下.NET 3.x的新特性:擴展方法。這裡需要說明的是我所說的.NET 3.x的新特性,其實是C# 3.0的一些新特性,考慮到LinQ等我就把這些特性叫做.NET 3.x新特性。可能這樣叫會有些歧義,但是我還是覺的這樣還好,閒話不多說讓我們進入正題。我覺得在C#3.0中引入自動化屬性等就已經減少了我們不少負擔,而擴展方法是我最喜歡的,它提供的可視化提示中顯得更為巧妙。但是我也會覺得有點煩瑣,當一個類的擴展方法太多時,就像有LinQ存在的情況下,會出現一大批的提示方法......
什麼是擴展方法?他的語法又是怎麼樣的?讓我們來看看。擴展方法必須定義在靜態函數中,擴展的方法也必須是靜態函數。這對於一些方法類的擴展提供了良好的支持,特別是對接口的補充更是極品啊,通常我們在用DataReader取對象時都需要一個轉換,而通過dr(DataReader實例)的一些方法如:GetString(int),GetInt32(ing)...其中的參數都是列的索引,通常我們都需要填寫列的名稱,這樣我們就可以對IDataReader接口進行擴展:
1 publicstaticclassExtensions
2 {
3 publicstaticstringGetString(thisIDataReaderdr,stringname)
4 {
5 returndr.GetString(dr.GetOrdinal(name));
6 }
7
8 publicstatic int GetInt32(thisIDataReaderdr,stringname)
9 {
10 returndr.GetInt32(dr.GetOrdinal(name));
11 }
12 }
從上面我們也可以知道他的語法,首先要有一個靜態類Extensions,對IDataReader接口的擴展,需要加入this IDataReader,而參數就是列名name。下面我們來看看他在VS中是怎麼智能提示的呢?
在上面我們可以看到在dr對象中出現了上面擴展的提示(extension),原來IDataReader自帶的只有一個GetString(int)方法,現在看到了有了個重載GetString(string)這樣是不是感覺上好一點?注意:如果你要用此擴展必須引入所在的命名空間。
在擴展方法中有一種繼承作用,如果你在當擴展方法類(如上面的IDataReader)擴展,則他的子類也同樣具有此擴展。如果我們想在所有類中都有的方法我們就可以對Object進行擴展,那樣在所有類中都會具有此擴展的方法,只要你引用了他所做的空間。例如:我們如果要判斷當前實例是否為集合或列表中的一個項,我們就可以對Object進行擴展,代碼如下:
1 public static bool IsEmailAddress(this string text) 2 { 3 Regex regex = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"); 4 return regex.IsMatch(text); 5 } 6 7 public static bool IsIn(this object o, IEnumerable collection) 8 { 9 foreach (object item in collection) 10 { 11 if (item.Equals(o)) 12 return true; 13 } 14 return false; 15 }
我們可以在所有的對象中得到此擴展,可以參考下圖:
我們知道其實整個LinQ都是方法的擴展,這個我們把它留到以後研究他時再說,因為LinQ有三大部分,一個是相對於類的,一個是To SQL的,還有一個是To XML的。當年都把他們叫做LinQ,DLinQ,XLinQ現在好像沒有這麼個教法,我們就順從微軟的意願吧。