通過前面的文章我們知道“泛型”是個“形容詞”,並且了解了 “泛型類” 和 “泛型數組” ,下面我們來看看泛型的其它的使用方式。
上一篇:C# -- 泛型(1)
<1>.泛型方法
上一篇文章說到用一個泛型類 SortHelper 來做一個冒泡排序的處理,下面回顧一下之前的代碼:
public class SortHelper<T> where T:IComparable { public void BubbleSort(T[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j].CompareTo(arr[j+1])>0) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
這里我們為了調用 BubbleSort,而將參數T傳遞給類 SortHelper,假如 SortHelper 類中,除了 BubbleSort 方法之外,還有其他的沒有使用到參數T的方法 比如:
public class SortHelper<T> where T:IComparable { public void BubbleSort(T[] arr) { //省略
} public void OtherMethod1() { //省略
} //此處省略N個OtherMethod
}
這里有 N 個 OtherMethod方法。
測試-調用 OtherMethod1:
static void Main(string[] args) { SortHelper<int> UserOtherMethod = new SortHelper<int>(); UserOtherMethod.OtherMethod1(); }
在實例化 UserOtherMethod 對象時 必須給 SortHelper 傳一個類型參數 這里是 int 。顯然這中情況下,我們僅僅是為了 BubbleSort 方法正常使用而定義泛型類,從而強迫其他使用 SortHelper 類其它方法
的實例傳遞一個參數,很明顯這是沒必要的,於是這個時候 ’泛型方法‘ 就出現了 ,修改代碼如下:
public class SortHelper2 { public void BubbleSort<T>(T[] arr) where T:IComparable { int length = arr.Length; for (int i = 0; i < length - 1; i++) { for (int j = 0; j < length - 1 - i; j++) { if (arr[j].CompareTo(arr[j + 1]) > 0) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
總結:
泛型方法和普通方法沒多大區別,僅僅在方法名后面加了“<T>”, 接着是括號里面的參數,最后是限定語句。
上述的這種情況,我們通過使用泛型方法,就可以避免每次使用泛型類傳參了。
<2>.泛型接口
回顧之前的文章我們 自己寫了一個 “cat” 類,並調用了一個接口“IComparable” 代碼如下:
public class cat:IComparable { public string name; public int price; public int CompareTo(object obj) {
cat catT = (cat)obj; return this.price.CompareTo(catT.price); }
public cat(string name, int price) { this.price = price; this.name = name; } }
這里粉紅色標記的部分我們實現了 “IComparable” 接口的 “CompareTo” 方法 這里沒有進行裝箱和拆箱。
因為cat是引用類型,而且“ return this.price.CompareTo(catT.price) ”這里調用的是 price (int型) 的 ComparaTo 方法,右鍵對int轉到定義查看代碼。
這里可以清楚的看到int類型實現了 IComparable 與 IComparable<int> 這兩個接口,也就是說它分別實現了這兩個接口的 ComparaTo() 方法,那這里又是調用那個接口的 ComparaTo() 方法呢?
實際上這里傳過來的參數是int類型,那么優先調用的是 ComparaTo(int value) 方法,這樣就避免了不必要的裝箱拆箱過程了。
上圖中是.NET 中 int 類型實現 IComparable 接口的 ComparaTo(object value) 方法,不難看出“紅箭頭”標記部分是執行裝箱拆箱操作的過程。
下圖是 int類型實現泛型版本的 IComparable<int> 的 ComparaTo(int value) 方法,如果對2種方法進行大量重復操作,不難發現使用泛型接口實現的方法性能比較好。
總結:
程序設計中應該盡量避免裝箱和拆箱操作,為了避免多次裝箱拆箱造成的性能影響 ,通過上面的例子我們可以知道使用泛型接口可以有效的避免這個問題:使用 IComparable<T> 而不使用 IComparable,這樣可以避免值類型的裝箱和取消裝箱操作。