4.9 使用泛型創建只讀集合
問題
您希望類中的一個集合裡的信息可以被外界訪問,但不希望用戶改變這個集合。
解決方案
使用ReadOnlyCollection<T>包裝就很容易實現只讀的集合類。例子如,Lottery類包含了中獎號碼,它可以被訪問,但不允許被改變:
public class Lottery
{
// 創建一個列表.
List<int> _numbers = null;
public Lottery()
{
// 初始化內部列表
_numbers = new List<int>(5);
// 添加值
_numbers.Add(17);
_numbers.Add(21);
_numbers.Add(32);
_numbers.Add(44);
_numbers.Add(58);
}
public ReadOnlyCollection<int> Results
{
// 返回一份包裝後的結果
get { return new ReadOnlyCollection<int>(_numbers); }
}
}
Lottery有一個內部的List<int>,它包含了在構造方法中被填的中獎號碼。有趣的部分是它有一個公有屬性叫Results,通過返回的ReadOnlyCollection<int>類型可以看到其中的中獎號碼,從而使用戶通過返回的實例來使用它。
如果用戶試圖設置集合中的一個值,將引發一個編譯錯誤:
Lottery tryYourLuck = new Lottery();
// 打印結果.
for (int i = 0; i < tryYourLuck.Results.Count; i++)
{
Console.WriteLine("Lottery Number " + i + " is " + tryYourLuck.Results[i]);
}
// 改變中獎號碼!
tryYourLuck.Results[0]=29;
//最後一行引發錯誤:// Error 26 // Property or indexer
// 'System.Collections.ObjectModel.ReadOnlyCollection<int>.this[int]'
// cannot be assigned to -- it is read only
討論
ReadOnlyCollection的主要優勢是使用上的靈活性,可以在任何支持IList或IList<T>的集合中把它做為接口使用。ReadOnlyCollection還可以象這樣包裝一般數組:
int [] items = new int[3];
items[0]=0;
items[1]=1;
items[2]=2;
new ReadOnlyCollection<int>(items);
這為類的只讀屬性的標准化提供了一種方法,並使得類庫使用人員習慣於這種簡單的只讀屬性返回類型。
閱讀參考
查看MSDN文檔中的“IList”和“Generic IList”主題。