• C#中索引器Indexer的学习使用


    索引器 顾名思义,是用来索引的,那么C#中索引器是用来索引什么的呢

    首先我们知道,C#中的数组是本身就可以索引的,那么C#中的类和结构呢,类和结构的实例是无法索引的,如果我们想让C#中类或者结构的实例也可以像数组一样进行索引,这个就是需要索引器了。这也就是索引器的作用

    索引器允许类或者结构的实例按照与数组相同的方式进行索引.  注意,是类或者结构的实例, 所以索引器不能用static来声明,索引器永远属于实例成员,因此不能声明为static

    举个简单的类子

        /// <summary>
        /// 简单的索引器例子
        /// </summary>
        public class SimpleIndexExample
        {
    
            private string[] name = new string[2];
    
    
            //索引器必须以this关键字来定义,索引器中的this其实就是类实例化之后的对象,这是正确的理解方式
            public string this[int index]
            {
    
                get { return name[index]; }
    
                set { name[index] = value; }
    
            }
    
        }
    
        public class Program
        {
    
            static void Main(string[] args)
            {
                //索引器SimpleIndexExample的使用
                SimpleIndexExample myIndex = new SimpleIndexExample();
    
                //对索引器赋值
                myIndex[0] = "Luke";
                myIndex[1] = "Mike";
    
                //输出索引器的值
                Console.WriteLine(myIndex[0]);
                Console.WriteLine(myIndex[1]);
               
    
            }
    
        }

     这样看来,索引器是不是和数组特别像,其实不然,索引器和数组有很多的区别

    区别1:  索引器的索引值(Index)类型不限定为整数; 我们知道,用来访问数组的索引值(Index)一定为整数,而索引器的索引值类型则可以为其他类型,不一定就是整数

    区别2:     索引器允许重载, 一个类不限定为只能定义一个索引器,只要索引器的函数签名不同,就可以定义多个索引器,可以重载它的功能

    区别3:  索引器不是一个变量,索引器没有直接定义数据存储的地方,而数组有,定义一个数组变量,它就是一个变量。而索引器不是,索引器具有Get和Set访问器.

    索引器与属性也同样有区别,区别如下:

    区别1  索引器以函数签名方式this来标识,而属性采用名称来标识,名称可以任意。

    区别2  索引器可以重载,而属性不能重载

    区别3   索引器必须是类或者结构的实例才有,所以不能用static来进行声明,它永远属于实例成员. 而属性可以使用static来进行声明.

        /// <summary>
        /// 以字符串为下标的索引器例子
        /// </summary>
        public class StringIndexExample
        {
    
            private Hashtable name = new Hashtable();
    
    
            //索引器以字符串为下标
            public string this[string index]
            {
    
                get { return name[index].ToString(); }
    
                set { name.Add(index, value); }
    
            }
    
        }
    
        public class Program
        {
    
            static void Main(string[] args)
            {
                //索引器StringIndexExample的使用
                StringIndexExample myIndex = new StringIndexExample();
    
                //对索引器赋值
                myIndex["A01"] = "Luke";
                myIndex["B01"] = "Mike";
    
                //输出索引器的值
                Console.WriteLine(myIndex["A01"]);
                Console.WriteLine(myIndex["B01"]);
               
    
            }
    
        }

    下面举一个比较复杂的索引器的例子,上面的索引器无论参数是int类型还是string类型,索引器都只有一个参数。下面我们举一个例子,有两个参数的索引器,同时,对索引器进行重载

        /// <summary>
        /// 定义一个成绩实体类
        /// </summary>
             
        public class Scores
        {
            /// <summary>
            /// 学生姓名
            /// </summary>
            public string StuName { get; set; }
    
            /// <summary>
            /// 课程ID
            /// </summary>
            public int CourseId { get; set; }
    
            
            /// <summary>
            /// 分数
            /// </summary>
            public int Score { get; set; }
    
        }
    
    
        /// <summary>
        /// 查找成绩的类中,定义索引器
        /// </summary>
        public class FindScore
        {
            private List<Scores> listScores;
    
            public FindScore()
            {
                listScores = new List<Scores>();
            }
    
            //含有两个参数的索引器,通过学生姓名和课程编号来查找和保存成绩
            public int this[string stuName, int courseId]
            {
                get
                {
                    Scores sResult = listScores.Find(s => s.StuName == stuName && s.CourseId == courseId);
                    if (sResult != null)
                    {
                        return sResult.Score;
                    }
                    else
                    {
                        return -1;
                    }
    
                }
    
                set
                {
    
                    listScores.Add(new Scores() { StuName = stuName, CourseId = courseId, Score = value });
    
                }
    
    
    
    
            }
    
            public List<Scores> this[string stuName]
            {
                get
                {
                    List<Scores> sListResult = listScores.FindAll(l => l.StuName == stuName);
                    return sListResult;
    
                }
            }
    
    
    
            static void Main(string[] args)
            {
    
                //多参数索引器和索引器重载
                FindScore fScore = new FindScore();
                fScore["Luke", 1] = 90;
                fScore["Luke", 2] = 85;
                fScore["Luke", 3] = 95;
                fScore["Mike", 1] = 75;
    
                //查找Mike课程编号为1的成绩
                Console.WriteLine("The score of Mike in Course 1 is:" + fScore["Mike", 1]);
    
                //查找Luke所有课程的成绩
                List<Scores> LukeListScores = fScore["Luke"];
    
                if (LukeListScores.Count > 0)
                {
                    foreach (Scores lukeS in LukeListScores)
                    {
                        Console.WriteLine(string.Format("Luke 课程编号{0} 成绩为{1}", lukeS.CourseId, lukeS.Score));
                    }
                }
                else
                {
                    Console.WriteLine("没有该学生的成绩");
                }
    
            }
    
    
        }

    本文参考 https://www.cnblogs.com/lxblog/p/3940261.html

  • 相关阅读:
    java数据类型转换
    复习Java基础
    最完整的台达PLC培训教程(沈阳工大)学习笔记1
    6.3.4 方法引用
    6.3.3函数式接口
    6.3 lambda 表达式
    java 核心技术卷一笔记 6 .2.3 接口 lambda 表达式 内部类
    java 核心技术卷一笔记 6 .2接口 lambda 表达式 内部类
    java 核心技术卷一笔记 6 .1.接口 lambda 表达式 内部类
    软件开发需求风险分析
  • 原文地址:https://www.cnblogs.com/wphl-27/p/9262018.html
Copyright © 2020-2023  润新知