【黑馬程序員】集合框架和自定義集合

---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------

集合的功能可以通過接口來實現,該接口不僅沒有限制我們使用基本的集合類(例如:System.Array),而且我們還可以創建自己的定製集合類。這些集合可以專用於要枚舉的對象(即要從中建立集合的對象)。這麼做的一個優點是定製的集合類可以是強類型化的,也就是說,從集合中提取項時,我們不需要把它們轉換爲正確的類型,反而可以直接使用。另一個優點是可以獲得專用的方法,比如可以提供獲得項子集的快捷方法,或其它一些自己編寫的特殊功能。

System.Collections名稱空間中的幾個接口提供了基本的集合功能:

IEnumerable:可以迭代集合中的項

ICollection:繼承於IEnumerable,可以獲取集合中項的個數,並能把項複製到一個簡單的數組類型中

IList:繼承於IEnumerable和ICollection,提供了集合的項列表,並可以訪問這些項,以及的其它一些與項列表相關的特殊功能

IDictionary:繼承於IEnumerable和ICollection,其功能類似於IList,但提供了可通過鍵碼值而不是索引訪問集合的項列表

通過以上接口,我們就自定義一個集合的基本框架。但我們還可以從一個類中派生自己的集合,例如System.Collections.CollectionBase類的許多實現方式,這是推薦使用的方式。CollectonBase類有接口IEnumerable、ICollection和IList,但只提供了一些要求的執行代碼,特別是IList的Clear()和RemoveAt()方法,以及ICollection的Count屬性。這些功能都需要用戶自己用代碼去實現。CollectionBase還提供了兩個受保護的屬性,它們可以訪問存儲的對象本身:List和InnerList,其中List可以通過IList訪問集合的項,InnerList則用於存儲項的ArrayList對象。例如:下面的代碼中,創建了一個存儲Animal對象的集合:

    /// <summary>
    /// 動物集合類(繼承自CollectionBase)
    /// </summary>
    public class Animals : CollectionBase
    {
        /// <summary>
        /// 向集合中添加動物對象
        /// </summary>
        /// <param name="newAnimal">要添加的元素</param>
        public void Add(Animal newAnimal)
        {
            List.Add(newAnimal);
        }

        /// <summary>
        /// 從集合中移除某動物對象
        /// </summary>
        /// <param name="oldAnimal">要移除的元素</param>
        public void Remove(Animal oldAnimal)
        {
            List.Remove(oldAnimal);
        }

        public Animals()
        {

        }

        /// <summary>
        /// 實現該集合可以通過索引訪問元素
        /// </summary>
        /// <param name="animalIndex">索引值</param>
        /// <returns>集合中該索引處的對象</returns>
        public Animal this[int animalIndex]
        {
            get
            {   //這裏需要進行顯式數據類型轉換,因爲Ilist.List屬性返回一個System.Object對象
                return (Animal)List[animalIndex];
            }
            set
            {
                List[animalIndex] = value;
            }
        }
main函數中的測試代碼如下:
static void Main(string[] args)
        {
            Console.WriteLine("Using custom collection class Animals:");
            Animals animalCollection = new Animals();
            animalCollection.Add(new Cow("Sarah"));
            animalCollection.Add(new Chicken("Roy"));
            foreach (Animal animal in animalCollection)
            {
                Console.WriteLine("New {0} object added to custom collection, " + "Name = {1}", animal.ToString(), animal.Name);
            }
            Console.WriteLine();

            animalCollection[0].Feed();
            animalCollection[1].Feed();

            Console.ReadKey();
        }
在以上代碼中,如果Animals類中沒有public Animal this[int animalIndex]這個函數,那麼測試代碼中的animalCollection[0].Feed()和animalCollection[1].Feed()便不能訪問訪問集合中的元素對象,也就不能調用Animal對象的Feed()方法。在上面的測試代碼中,我們從animalCollection集合中取出元素時無需進行轉換,因爲這個集合中只能存儲Animal類型的元素。


以上是通過實現IList接口讓集合可以通過索引來訪問元素,其實我們還可以通過實現IDictionary接口來允許集合通過鍵碼值訪問元素。與上面的方法一樣,只不過這個集合需要繼承自DictionaryBase,它也實現了IEnumerable和ICollection接口,提供了對任何集合都相同的集合處理功能。DictionaryBase也執行Clear()、Count()和Remove()方法,但不執行RemoveAt()方法,因爲RemoveAt()是IList接口上的一個方法。要注意的是在通過Add()向字典集合中添加元素是,要同時添加鍵碼值和元素對象。然後我們就可以通過鍵碼值來訪問集合中的元素。



---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章