您好,登錄后才能下訂單哦!
引言:
前面專題主要介紹了C#1中的2個核心特性——委托和事件,然而在C# 2.0中又引入一個很重要的特性,它就是泛型,大家在平常的操作中肯定會經常碰到并使用它,如果你對于它的一些相關特性還不是很了解,那就讓我們一起進入本專題的學習的。
一、泛型的是什么
泛型的英文解釋為generic,當然我們查詢這個單詞時,更多的解釋是通用的意思,然而有些人會認為明明是通用類型,怎么成泛型了的,其實這兩者并不沖突的,泛型本來代表的就是通用類型,只是微軟可能有一個比較官方的此來形容自己引入的特性而已,既然泛型是通用的, 那么泛型類型就是通用類型的,即泛型就是一中模子。 在生活中,我們經常會看到模子,像我們平常生活中用的桶子就是一個模子,我們可以用桶子裝水,也可以用來裝油,牛奶等等,然而把這些都裝進桶子里面之后,它們都會具有桶的形狀(水,牛奶和油本來是沒有形的),即具有模子的特征。同樣,泛型也是像桶子一樣的模子,我們可以用int類型,string類型,類去實例化泛型,實例化之后int,string類型都會具有泛型類型的特征(就是說可以使用泛型類型中定義的方法,如List<T>泛型,如果用int去初始化它后,List<int>的實例就可以用List<T>泛型中定義的所有方法,用string去初始化它也一樣,和我們生活中的用桶裝水,牛奶,油等非常類似)
二、C# 2.0為什么要引入泛型
大家通過第一部分知道了什么是泛型,然而C#2.0中為什么要引入泛型的?這答案當然是泛型有很多好處的。下面通過一個例子來說明C# 2.0中為什么要引入泛型,然后再介紹下泛型所帶來的好處有哪些。
當我們要寫一個比較兩個整數大小的方法時,我們可能很快會寫出下面的代碼:
public class Compare { // 返回兩個整數中大的那一項 public static int Compareint(int int1, int int2) { if (int1.CompareTo(int2) > 0) { return int1; } return int2; } }
然而需求改變為又要實現比較兩個字符串的大小的方法時,我們又不得不在類中實現一個比較字符串的方法:
// 返回兩個字符串中大的一項 public static string Comparestring(string str1, string str2) { if (str1.CompareTo(str2) > 0) { return str1; } return str2; }
如果需求又改為要實現比較兩個對象之間的大小時,這時候我們又得實現比較兩個對象大小的方法,然而我們中需求中可以看出,需求中只是比較的類型不一樣的,其實現方式是完全一樣的,這時候我們就想有沒有一種類型是通用的,我們可以把任何類型當做參數傳入到這個類型中去實例化為具體類型的比較,正是有了這個想法,同時微軟在C#2.0中也想到了這個問題,所以就導致了C#2.0中添加了泛型這個新的特性,泛型就是——通用類型,有了泛型之后就可以很好的幫助我們剛才遇到的問題的,這樣就解決了我們的第一個疑問——為什么要引入泛型。下面是泛型的實現方法:
public class Compare<T> where T : IComparable { public static T CompareGeneric(T t1, T t2) { if (t1.CompareTo(t2) > 0) { return t1; } else { return t2; } } }
這樣我們就不需要針對每個類型實現一個比較方法,我們可以通過下面的方式在主函數中進行調用的:
public class Program { static void Main(string[] args) { Console.WriteLine(Compare<int>.CompareGeneric(3, 4)); Console.WriteLine(Compare<string>.CompareGeneric("abc", "a")); Console.Read(); } }
通過上面的代碼大家肯定可以理解C# 2.0中為什么要引入泛型的,然而泛型可以給我們帶什么好處的呢?從上面的例子可以看出,泛型可以幫助我們實現代碼的重用,大家很清楚——面向對象中的繼承也可以實現代碼的重用,然而泛型提供的代碼的重用,確切的說應該是 “算法的重用”(我理解的算法的重用是我們在實現一個方法中,我們只要去考慮如何去實現算法,而不需要考慮算法操作的數據類型的不同,這樣的算法實現更好的重用,泛型就是提供這樣的一個機制)。
然而泛型除了實現代碼的重用的好處外,還有可以提供更好的性能和類型安全,下面通過下面一段代碼來解釋下為什么有這兩個好處的。
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace GeneralDemo { public class Program { static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); // 非泛型數組 ArrayList arraylist = new ArrayList(); // 泛型數組 List<int> genericlist= new List<int>(); // 開始計時 stopwatch.Start(); for (int i = 1; i < 10000000; i++) { genericlist.Add(i); ////arraylist.Add(i); } // 結束計時 stopwatch.Stop(); // 輸出所用的時間 TimeSpan ts = stopwatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds/10); Console.WriteLine("運行的時間: " + elapsedTime); Console.Read(); } } }
當我們把 arraylist.Add(i);這行代碼注釋掉來測試向泛型數組中加入數據的運行時間,下面是我機器的上運行的一個截圖:
當我們把 genericlist.Add(i);這行代碼注釋掉來測試向一個非泛型數組中加入數據的運行時間,下面附上我機器上的運行的時間截圖:
從兩個結果中就可以明顯看出 向泛型數組中的加入數據的效率遠高于非泛型數組。有圖有真相,這樣就充分說明泛型的另一個好處——高性能,然而泛型類型也保證了類型安全(大家都知道,C#是一個強類型的語言的,強類型指的是在每定義一個變量都需要指定變量的類型),當我們向這個泛型genericlist數組中添加string類型的值時,此時就會造成編譯器報錯 “無法從“string”轉換為’int‘ ”
三、小結
本專題主要和大家分享了C# 2.0中為什么會引入委托,以及委托的好處,相信通過上面的介紹大家已經對委托有一個簡單的認識以及對于泛型所帶來的好處也有一個全面的認識,對于泛型的高性能本專題并沒有給出原因,這個內容將會在下面一個專題向大家介紹。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。