天天看點

使用ReadOnlyCollection建立隻讀集合

使用泛型建立隻讀集合

問題

您希望類中的一個集合裡的資訊可以被外界通路,但不希望使用者改變這個集合。

解決方案

使用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);

這為類的隻讀屬性的标準化提供了一種方法,并使得類庫使用人員習慣于這種簡單的隻讀屬性傳回類型。