hi,you guys。算法
今天咱們繼續學習<叩響c#之門>,今天咱們學習的內容是集合與泛型。集合、泛型是咱們項目開發中常常會用的知識。學好泛型、集合,對咱們開發工做有很大的幫助。編程
集合c#
物以類聚,相同的東西須要歸於一類。咱們經常將相互關聯的對象組成集合,天然數組成天然數集。同班同窗組成班級,詩人作的詩篇,組成詩集。集合中的對象,稱爲元素(Element)。C#爲咱們提供一組功能強大的集合類,實現了多種不一樣類型的集合,咱們能夠根據實際用途選擇恰當的集合類型。下表,是FCL(Framework Common Library)類庫爲咱們提供的部分集合類。數組
除了Array在System命名空間下,其他的類都位於System.Collections命名空間下。這些類經過直接或間接的繼承一些接口,來實現其自身強大的功能。咱們以前在項目中用過foreach循環語句,遍歷一個集合或數據集。那麼是如何foreach是如何實現對集合或數據集的遍歷的呢?(與其說是遍歷,不如說是迭代。關於迭代概念,你們能夠參考一些數據結構書籍的遞歸算法)。原來FCL提供的集合類,都直接或間接的實現了IEnumerable接口,這個接口聲明瞭一個名爲GetIEnumerator()方法。這個方法返回一個繼承了IEnumerator接口的類,咱們一般將這個類稱爲迭代器。安全
//IEnumerable接口 public interface IEnumerable { IEnumerator GetIEnumerator(); }
IEnumerable接口類數據結構
//IEnumerator接口 public interface IEnumerator { bool MoveNext(); //獲取下一個元素 object Current{get;} //獲取當前元素 void Reset(); //將枚舉數設置爲其初始位置 }
IEnumerator接口類性能
foreach語句就是經過訪問迭代器來獲取集合中的元素。ICollection接口也是一個很基礎的接口,它繼承了IEnumerable接口,而且添加了一個Copy()方法,和一個Count屬性以及兩個用於同步的屬性。學習
//ICollection接口 public interface ICollection:IEnumerable { void Copy(System.Array array,int index); //複製到數組 int Count{get;} //元素個數 bool IsSynchronized; //是否同步 object SyncRoot{get;} //用於同步的對象 }
IList接口、IDictionary接口都繼承於ICollection接口。this
關於各個集合類的一些方法,你們能夠下去本身練習一下。由於,本章主要講解的是泛型類。其實,在項目中你們更多的會去使用泛型,由於集合存在一個弊端。spa
集合類的弊端
你們看看下面的代碼:
ArrayList list=new ArrayList(); lsit.Add(10); //添加元素 int n=(int)lsit[0]; //取出元素
由於全部類型都繼承於object的類型,因此當咱們調用.Add()方法,向集合中添加元素時,系統會默認爲object類型。此時,若是添加的元素不是引用類型而是值類型,那麼在向集合添加元素時,就會進行裝箱操做,將值類型轉換爲引用類型。一樣,在咱們讀取元素時,須要拆箱操做,將object的類型轉換爲值類型。這樣作,會有三個缺點:
第1、在裝箱、拆箱的過程當中,可能會形成必定的性能損失。
第2、什麼類型的數據都往集合中放,不利於編譯器進行嚴格的類型安全檢查。
第3、顯示轉換類型,下降了程序的可讀性。Note(如今計算機愈來愈快,性能也不是惟一目標了。軟件開發成本在於軟件維護與升級。因此,提升代碼可讀性能夠下降軟件開發成本呢。)
ArrayList list=new ArrayList(); list.Add(10); list.Add("hello"); foreach(int element in list) { int n=(int)element; }
上面這段代碼,編譯不會出錯。運行會出現,由於」hello」不能轉換爲int類型。如今你們看出集合類的弊端了吧,那麼泛型類又有什麼地方強於集合呢?其實不難想象,泛型強於集合的地方,必定是集合比較薄弱的地方。集合薄弱的地方就在,集合類的元素類型沒有限制。
泛型
泛型與集合的功能基本一致,惟一的不一樣點在於,泛型類的元素類型受咱們控制,是咱們指定的類型,而不是萬物之祖的object類型。泛型具備一個參數列表<T>,在整個類裏用T表明元素類型,T的類型是不肯定的,是抽象類型。在咱們實例化類時,將抽象類型的元素具體化,具體類型的參數將代替T。看程序:
// 泛型類 public class Generic<T> { public void Check() { Console.WriteLine(this.GetType()); //輸出T的類型 } } //實例化泛型類 Generic<int> instanceInt=new Generic<int>(); instanceInt.Check(); //輸出的類型爲System.Int32 Generic<String> instanceString=new Generic<String>(); instanceString.Check(); //輸出的類型爲System.String;
泛型類中的T,是抽象類型。實例化時,纔會將其具體化。例如上面的instanceInt,就是將泛型類中的T,具體化爲Int類型。instanceString,就泛型類的T具體化爲String類型.咱們能夠定義泛型類,贊成也可定義泛型方法,泛型接口等。看下面的代碼:
//泛型類 public static void Swap<T>(ref T a,ref T b) { T t=a; a=b; b=t; }
此時的a,b都是抽象的,都是未知的類型。
Static void Main(string[] args) { int x=100; int y=200; Swap<int> (ref x,ref y); Console.WriteLine("x={0},y={1}",x,y); }
咱們在調用泛型方法時,將參數具體化了。
C#爲咱們提供了一些泛型類:
List<T>
Stack<T>
Queue<T>
SortedList<TKey,TValue>
Dictionary<TKey,TValue>
關於他們的一些方法,你們能夠查看相關手冊。學會經過查看手冊來學習編程,是很重的。好了今天的泛型、集合就到這裏了。最後,我把做者講的一句話,給你們分享一下。「實踐中磨練編程技能,思考中感悟編程本質」。