C#自定義集合

C#自定義集合


     對於基於Unity遊戲引擎來深入開發商業級高品質遊戲的廣大遊戲開發人員來說,使用C#語言來開發諸如“對象緩衝池”等技術應用來說,開發我們的“自定義集合”是非常必要的。


     根據筆者經驗,一個好的C#"自定義集合"需要滿足以下需求:

   1: 可以使用foreach 方便的遍歷集合元素。
   2: 採用索引器技術,提供直接的方式訪問或者賦值內部元素。

   3: 提供類似 IList 接口的常用訪問方法:
     Add() 、Clear()、Insert()、Remove()


    ​本技術需要讀者提前具備集合、索引器等相關知識(讀者可以看筆者以前博客介紹文章),爲了好說明,先給出4個演示類,組成一個C#自定義集合的演示示例。


第一個: 實體類

    public class Person
    {
        //public static int i;
        private string _Name;
        private int _Age;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        public int Age
        {
            get { return _Age; }
            set { _Age = value; }
        }

        //public Person()
        //{
        //    i++;
        //    name = "張三" + i.ToString();
        //}

        public Person(string strName,int intAge)
        {
            _Name = strName;
            _Age = intAge;
        }       
    }


第二個: 集合核心類

    public class PersonCollection:IEnumerable //表示可遍歷可枚舉的集合接口
    {
        //保存Object 類型的 數組。
        ArrayList al = new ArrayList();


        /// <summary>
        /// 實現了IEnumberable 後,返回一個迭代器對象,但具體的接口子類由程序員
        /// 自己定義。
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            return new MyGetEnumberater(this.al);
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Person this[int index]
        {
            get { return (Person)al[index]; }
        }
      
        public void Add(Person p)
        {
            al.Add(p);
        }

        public void AddRange(ICollection ip)
        {
            al.AddRange(ip);
        }

        public void Clear()
        {
            al.Clear();
        }

        public void Insert(int index,Person value)
        {
            al.Insert(index,value);
        }

        public int IndexOf(Person p)
        {
            return al.IndexOf(p);
        }

        public void RemoveAt(int index)
        {
            al.RemoveAt(index);
        }

        public void Remove(Person p)
        {
            if(al.Contains(p))
            {
                int temp = IndexOf(p);
                RemoveAt(temp);
            }
        }
    }//Class_end



第3個: 自定義的“迭代器”類

    public class MyGetEnumberater:IEnumerator
    {
        int i = 0;
        ArrayList ps;

        public MyGetEnumberater(ArrayList p)
        {
            ps = p;
        }

        /// <summary>
        /// 得到當前元素
        /// </summary>
        public object Current
        {
            get { return ps[i++]; }  //注意這裏的i++ ,是先運算再自增。
            //相當於
            //object o=ps[i];
            //i++;
            //return o;

        }

        /// <summary>
        /// 移動到下一個元素
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (i > ps.Count - 1)
            {
                return false;
            }
            return true;
        }

        //重置
        public void Reset()
        {
            i = 0;
        }
    }


第4個:測試“自定義集合”的測試類

    class Program
    {
        static void Main(string[] args)
        {
            PersonCollection pc = new PersonCollection();
            pc.Add(new Person("張三",10));
            pc.Add(new Person("李四",20));
            pc.Add(new Person("王五",25));


            //本質foreach 就是調用接口中的一個方法
            foreach (Person item in pc)
            {
                Console.WriteLine(item.Name+"  "+item.Age);
            }
            //使用自定義的“索引器”訪問。
            Console.WriteLine("-----使用索引器訪問------");
            Console.WriteLine(pc[0].Name);
            Console.WriteLine(pc[0].Age);
            Console.WriteLine(pc[1].Name);
            Console.WriteLine(pc[1].Age);
            Console.WriteLine(pc[2].Name);
            Console.WriteLine(pc[2].Age);
            Console.ReadLine();
        }
    }


    ​讀者可以通過拷貝以上代碼,建立測試用例。通過Program 類測試我們發現,我們自己定義的PersonCollection.cs 類,是可以與ArrayList集合類似,使用foreach 做迭代輸出,使用“索引器”來對集合中數據作直接訪問。

    我們自定義的“迭代器”類(MyGetEnumberater),其實就是foreach 的內部原理:

    ​foreach(Person p in PC){}

    ​等價於如下:
    ​IEnumberable eab=PC as IEnumerable;     //可迭代接口
    ​IEnumberator etor=eab.GetEnumerator(); //迭代接口
    ​while(etor.MoveNext())
    ​{
         ​Person p=etor.Current;
         ​//........
    ​}​


    ​好了,本節關於C#“自定義集合“知識點,就介紹到這裏,大家如果有問題,可以隨時留言討論。謝謝!

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