Abstract
在OO設計中,對應於Relational Database的一筆資料,我們會用一個object,如Customer,但多筆資料呢?有些人會用DataSet,有些人會用List<Customer>,這些方法都不錯,但若要設計自己的Collection:Customers type,那該怎麼做呢?

Introduction
使用DataSet(DataTable,DataReader....)或List<Customer>這些代表Collection,理論上並沒有什麼錯,事實上很多人也都這樣用,缺點就是比較沒有OO的flavor。理想上,既然有Customer class代表一筆資料,就應該有Customers class代表多筆資料,而N-Tiers間的傳輸應該是Customers collection,而非DataSet或List<Customer>。

要產生自己的Collection,有兩種方式,一個是.NET 1.0的方式,一個是.NET 2.0的方式。

.NET 1.0方式(在.NET 2.0仍然可以使用)
繼承CollectionBase,CollectionBase是一個abstract class,implement了IList ,ICollection,IEnumerable,已經為Collection做好了基礎架構,我們要做的就是overload this[]、IndexOf()、Add()、Remove()就好,其他的事情,CollectionBase已經幫我們做好了。

(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)



C#

 1}


執行結果

(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)Cerlina


在Member class中,25行到40行

}


整體的目標是為了改寫object的比較方式,在.NET,預設是用reference比較object是否相同,但這對Collection的IndexOf(),Remove()有很大的影響,所以我override了Equals()和GetHashCode(),並對==和!=做了operator overloading。

CollectionBase原本都有實現IndexOf(),Add(),Remove(),但因只針對Object而非Member,所以針對了Member overload了IndexOf(),Add(),Remove(),另外使用了indexer是為了方便Collection的使用。

C++/CLI

 1}


執行結果

(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)Cerlina


.NET 2.0 (使用Collection<T>)
繼承Collection<Member>,因為是泛型,所以不用再overload IndexOf(),Add(),Remove(),也不用在定義indexer,因為泛型會直接使用Member,所以code非常精簡。

Collection<T>的架構頗複雜,implement了IEnumerable,IEnumerable<T>,ICollection,ICollection<T>,IList,IList<T>。
(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)
C#

 1}


執行結果

(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)Cerlina


35行

}


非常精簡,只需繼承Collection<Member>即可。

C++/CLI

 1}


執行結果

(原創) 如何建立自己的Collection? (.NET) (C#) (C++/CLI) (C/C++)Cerlina


Conclusion
泛型最基本的應用,也是最原始的應用,就是在container,若用OO,只能用多型(多態)的技術,讓container放Object type,進Container須轉型成Object,出Container需再轉回各type,若用泛型,就可直接將各type放進container,不需轉型,不只速度提升,且code也非常的精簡。

相关文章: