C#自定义集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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#“自定义集合“知识点,就介绍到这里,大家如果有问题,可以随时留言讨论。谢谢!

本文出自 “刘老师讲Unity” 博客,请务必保留此出处http://liuguozhu.blog.51cto.com/9142031/1846382

以上是关于C#自定义集合的主要内容,如果未能解决你的问题,请参考以下文章

《C#本质论》读书笔记(16)构建自定义集合

C# - 如何在不使用索引器的情况下获取自定义集合的第一项?

通过Lua迭代器自定义实现对c#集合的遍历

自用 .net C# List集合和DataTable互转,可自定义表头

C# 自定义排序

C#怎么定义泛型集合类型的函数,返回一个集合