• 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#“自定义集合“知识点,就介绍到这里,大家如果有问题,可以随时留言讨论。谢谢!

  • 相关阅读:
    Html5实现iPhone开机界面
    Html5游戏开发-145行代码完成一个RPG小Demo
    HTML5开源RPG游戏引擎lufylegendRPG 1.0.0发布
    如何制作一款HTML5 RPG游戏引擎——第五篇,人物&人物特效
    如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话
    如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景
    html5游戏开发-零基础开发《圣诞老人送礼物》小游戏
    如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果
    如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现
    读CopyOnWriteArrayList有感
  • 原文地址:https://www.cnblogs.com/LiuGuozhu/p/5841865.html
Copyright © 2020-2023  润新知