IListSource 讓使用者透過 GetList() 存取內容,ContainsListCollection 屬性允許修改整個集合結構。使用介面,DataSet 內部物件可被存取,但整體結構不可修改;呼叫者也無法用 DataSet 方法修改可用行為、在資料上移動約束或添加功能。
型別以類別方式暴露屬性時,暴露該類別完整介面。用介面可選擇只暴露部分想提供的方法與屬性。類別上實作介面的細節,日後可修改(原則 23)。
假設建立應用程式管理員工、客戶、廠商。彼此無關,無繼承關係,但共享功能:都有名字,可能在 Windows 控制項顯示名字:
public class Employee { public string Name { get { return string.Format("{0}, {1}", _last, _first); } } }
public class Customer { public string Name { get { return _customerName; } } }
public class Vendor { public string Name { get { return _vendorName; } } }
不應共享基類。但共享屬性:姓名、地址、連絡電話。應在介面建立這些屬性:
public interface IContactInfo
{
string Name { get; }
PhoneNumber PrimaryContact { get; }
PhoneNumber Fax { get; }
Address PrimaryAddress { get; }
}
public class Employee : IContactInfo { /* 實作 */ }
對不相關型別使用通用功能,介面簡化程式設計任務。
結構放入箱子時,箱子實現結構上所有介面。用介面指標存取結構,無需拆箱即可直接存取。範例:結構定義連結與說明,實作 IComparable:
public struct URLInfo : IComparable
{
private string URL, description;
public int CompareTo(object o) { /* 實作 */ }
public int CompareTo(URLInfo other) { return URL.CompareTo(other.URL); }
}
可為 URLInfo 建立有序表。URLInfo 加入鏈表時被裝箱,但 Sort() 不需拆箱即可呼叫 CompareTo()。仍需拆箱參數 other,但調用 IComparable.CompareTo() 時左側物件免拆箱。
基類描述並實作具體相關型別行為。介面描述原子級功能塊,不相關具體型別皆可實作。介面以功能塊描述物件行為。理解差異,可建立表達力更強、面對修改更有彈性的設計。類別繼承定義相關型別;實作介面暴露部分功能存取這些型別。