《精通C#》索引器与重载操作符(11.1-11.2)

时间:2021-03-03 16:33:05

1.索引器方法结构大致为<modifier><return type> this [argument list],它可以在接口中定义:  在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。以下代码把索引器声明为接口IImplementMe的一部分:

interface IImplementMe {  string this[int index]  {  get;  set;  }

相应实现的类则必须为IimplementMe的索引器具体定义get和set访问函数。

索引器可以称之为有参数的属性,它与属性的区别在于属性名称不能相同,不可重载,索引器可以。属性可以使static的,但是索引器必须是实例化的。在我看来索引器的作用在于可以改变现有的一些索引器的索引方式,比如数组的所以方式是以int作为下标,查询相应数据,但是我可以重写索引,使数组的索引以string进行。

例:

namespace Study
{
    class Program
    {
        static void Main(string[] args)
        {
            ScoreIndex s = new ScoreIndex();
            s["张三", 1] = 90;
            s["张三", 2] = 100;
            s["张三", 3] = 80;
            s["李四", 1] = 60;
            s["李四", 2] = 70;
            s["李四", 3] = 50;
            Console.WriteLine("张三课程编号为1的成绩为:" + s["张三",1]);
            Console.WriteLine("张三的所有成绩为:");
            ArrayList temp;
            temp = s["张三"];
            foreach (IndexClass b in temp)
            {
                Console.WriteLine("姓名:" + b.Name + "课程编号:" + b.CourseID + "分数:" + b.Score);
            }
            Console.ReadKey();
        }
    }
    class IndexClass
    {
        private string _name;
        private int _courseid;
        private int _score;
        public IndexClass(string _name, int _courseid, int _score)
        {
            this._name = _name;
            this._courseid = _courseid;
            this._score = _score;
        }
        public string Name
        {
            get { return _name; }
            set { this._name = value; }
        }
        public int CourseID
        {
            get { return _courseid; }
            set { this._courseid = value; }
        }
        public int Score
        {
            get { return _score; }
            set { this._score = value; }
        }
    }
    class ScoreIndex
    {
        private ArrayList arr;
        public ScoreIndex()
        {
            arr = new ArrayList();
        }
        public int this[string _name, int _courseid]
        {
            get
            {
                foreach (IndexClass a in arr)
                {
                    if (a.Name == _name && a.CourseID == _courseid)
                    {
                        return a.Score;
                    }
                }
                return -1;
            }
            set
            {
                arr.Add(new IndexClass(_name, _courseid, value)); //arr["张三",1]=90
            }
        }
        //重载索引器
        public ArrayList this[string _name]
        {
            get
            {
                ArrayList temp = new ArrayList();
                foreach (IndexClass b in arr)
                {
                    if (b.Name == _name)
                    {
                        temp.Add(b);
                    }
                }
                return temp;
            }
        }
    }
}

2.操作符重载:

操作符重载是将现有的一些操作符的功能进行改变,例如两个类相加,相减,相比较等,它提供Operaor关键字进行重载,必须与static关键字联合使用。例:

namespace ContainerAndOperator
{
    /// <summary>
    /// 索引器,此类已成为容器类,索引器大部分使用在容器类中
    /// 使用IEnumerable与GetEnumerator()目的在于使这个类可以进行foreach
    /// </summary>
    public class ContainerClass : IEnumerable
    {
        private ArrayList people = new ArrayList();
        public Person this[int index]//Person为返回的值类型,int为输入的索引值的类型,this用来定义索引器
        {
            get { return (Person)people[index]; }
            set { people.Insert(index, value); }
        }

        public IEnumerator GetEnumerator()
        {
            return people.GetEnumerator();
        }
    }

    public class Person
    {
        public string name { get; set; }
        public string Id { get; set; }
        public int Age { get; set; }
        /// <summary>
        /// 重构二元操作符
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public static Person operator +(Person p1,Person p2)
        {
            return new Person(p1.name + "-" + p2.name, p1.Id + "-" + p2.Id, p1.Age + p2.Age);
        }
        public static string operator -(Person p1, Person p2)
        {
            return p1.name+"-"+p2.Id;
        }
        public Person(){}
        public Person(string n,string i,int a)
        {
            name = n;
            Id = i;
            Age = a;
        }
    }
}

namespace ContainerAndOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            ContainerClass con = new ContainerClass();
            con[0] = new Person("homer", "11", 11);
            con[1] = new Person("homer1", "12", 12);
            con[2] = new Person("homer2", "13", 13);
            Console.WriteLine(con[2].name);
            foreach(Person s in con)
            {
                Console.WriteLine(s.name);
            }
            Console.WriteLine("*******************************");
            Person p3 = con[1] + con[2];
            Console.WriteLine(p3.name);
            Console.WriteLine(con[1] - con[2]);
            Console.ReadLine();
        }
    }
}

因为有时候我们可能需要对两个类进行对比,已完成一些特定的功能,但是,原生的操作符不支持的情况下,我们就可以重载操作符。