前面的代碼創建了一個整型的數組鏈表,而且使用 IList接口指針添加了兩個不同的值到集合中。通過重載OnInsert()方法, IntList類在添加類型時會檢測類型,如果不是一個整數時,會拋出一個異常。 基類給你實現了默認的方法,而且給我們提供了機會在我們自己的類中實現詳細 的行為。
CollectionBase這個基類提供的一些實現可以直接在你的類中 使用。你幾乎不用寫太多的代碼,因為你可以利用它提供的公共實現。但 IntList的公共API是通過CollectionBase實現接口而來的: IEnumerable,ICollection和IList接口。CollectionBase實現了你可以直接使用 的接口。
現在我們來討論用接口來做參數和返回值。一個接口可以被任 意多個不相關的類型實現。比起在基類中編碼,實現接口的編碼可以在開發人員 中提供更強的伸縮性。因為.Net環境中強制使用單繼承的,這使得實現接口這一 方法顯得很重要。
下面兩個方法完成了同樣的任務:
public void PrintCollection( IEnumerable collection )
{
foreach( object o in collection )
Console.WriteLine( "Collection contains {0}",
o.ToString( ) );
}
public void PrintCollection( CollectionBase collection )
{
foreach( object o in collection )
Console.WriteLine( "Collection contains {0}",
o.ToString( ) );
}
第二個方法的重用性遠不及第一個。Array,ArrayList, DataTable,HashTable,ImageList或者很多其它的集合類無法使用第二個方法 。讓方法的參數使用接口,可以讓程序具有通用性,而且更容易重用。
用接口為類定義API函數同樣可以取得很好的伸縮性。例如,很多應用程序使用 DataSet與你的應用程序進行數據交換。假設這一交流方法是不變的,那這太容 易實現了:
public DataSet TheCollection
{
get { return _dataSetCollection; }
}
然而這讓你在將來很 容易遇到問題。某些情況下,你可能從使用DataSet改為暴露一個DataTable,或 者是使用DataVIEw,甚至是使用你自己定義的對象。任何的改變都會破壞這些代 碼。當然,你可能會改變參數類型,但這會改變你的類的公共接口。修改一個類 的公共接口意味著你要在一個大的系統中修改更多的內容;你須要修改所有訪問 這個公共接口的地方。
緊接著的第二個問題麻煩問題就是:DataSet類提 供了許多方法來修改它所包含的數據。類的用戶可能會刪除表,修改列,甚至是 取代DataSet中的所有對象。幾乎可以肯定這不是你想要的。幸運的是,你可以 對用戶限制類的使用功能。不返回一個DataSet的引用,你就須要返回一個期望 用戶使用的接口。DataSet支持IListSource接口,它用於數據綁定:
using System.ComponentModel;
public IListSource TheCollection
{
get { return _dataSetCollection as IListSource; }
}