# 索引器使用总结 ## 功能 通常情况下,属性只能访问单一的字段(一个属性对一个字段进行封装),如果想访问多个数据成员,就需要使用索引器。索引器是类的特殊成员,它可以根据索引在多个成员中进行选择,能够让对象以类似数组的方式来存取。索引器的数据类型必须是统一的 ## 语法 ```C# [修饰符] 数据类型 this[索引类型 index] { get { //返回参数值,往往跟索引的不同返回不同的字段,用选择语句 } set { //设置赋值语句 } } namespace 索引器 { class Student { private string name; private string sex; private string tel; //索引器 public string this[int index]//【访问修饰符】 数据类型 this【索引器类型 index】 语法格式 { get { switch (index) { case 1://由于return就有返回功能和结束功能所以这里的break可以省略因为写了运行不到这句代码 return name; case 2: return sex; case 3: return tel; default: throw new ArgumentOutOfRangeException("index");//抛出异常 } } set { switch (index) { case 1://这里必须要有break结束语句,因为每个case的功能语句都是赋值且没有结束语句所以这里需要break name = value; break; case 2: sex = value; break; case 3: tel = value; break; default: throw new ArgumentOutOfRangeException("index");//抛出异常 } } } public void Speak() { Console.WriteLine("我叫{0},我是{1}生,我的电话是{2}", this[1], this[2], this[3]);//this[] this表示的是索引器,this[]表示访问向对应的字段。 } } } namespace 索引器 { class Program { static void Main(string[] args) { Student stu = new Student();//实例化对象 stu[1] = "xxx";//给索引器以数组的方式赋值 stu[2] = "男"; stu[3] = "13122022202"; stu.Speak(); Console.ReadKey(); } } } ``` ## 索引器(Indexer) 索引器允许类或者结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于他们的访问采用参数。 最简单的索引器的使用 ```C# /// /// 最简单的索引器 /// public class IDXer { private string[] name=new string[10]; //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象 public string this[int index] { get { return name[index]; } set { name[index] = value; } } } public class Program { static void Main(string[] args) { //最简单索引器的使用 IDXer indexer = new IDXer(); //“=”号右边对索引器赋值,其实就是调用其set方法 indexer[0] = "张三"; indexer[1] = "李四"; //输出索引器的值,其实就是调用其get方法 Console.WriteLine(indexer[0]); Console.WriteLine(indexer[1]); Console.ReadKey(); } } ``` ## 索引器与数组的区别 索引器的索引值(Index)类型不限定为整数: 用来访问数组的索引值(Index)一定为整数,而索引器的索引值类型可以定义为其他类型。 索引器允许重载 一个类不限定为只能定义一个索引器,只要索引器的函数签名不同,就可以定义多个索引器,可以重载它的功能。 索引器不是一个变量 索引器没有直接定义数据存储的地方,而数组有。索引器具有 Get 和 Set 访问器。 ## 索引器与属性的区别 索引器以函数签名方式 this 来标识,而属性采用名称来标识,名称可以任意 索引器可以重载,而属性不能重载。 索引器不能用 static 来进行声明,而属性可以。索引器永远属于实例成员,因此不能声明为 static。 ```C# //以字符串为下标的索引器 public class IDXer2 { private Hashtable name = new Hashtable(); //以字符串为下标的索引器 public string this[string index] { get { return name[index].ToString(); } set { name.Add(index, value); } } } ``` ```C# public class Program { static void Main(string[] args) { //以字符串为下标的索引器 IDXer2 indexer2 = new IDXer2(); indexer2["A01"] = "张三"; indexer2["A02"] = "李四"; Console.WriteLine(indexer2["A01"]); Console.WriteLine(indexer2["A02"]); Console.ReadKey(); } } ``` ## 多参数索引器及索引器的重载 ```C# /// /// 成绩类 /// public class Scores { /// /// 学生姓名 /// public string StuName { get; set; } /// /// 课程ID /// public int CourseId { get; set; } /// /// 分数 /// public int Score { get; set; } } /// /// 查找成绩类(索引器) /// public class FindScore { private List listScores; public FindScore() { listScores = new List(); } //索引器 通过名字&课程编号查找和保存成绩 public int this[string stuName, int courseId] { get { Scores s = listScores.Find(x => x.StuName == stuName && x.CourseId == courseId); if (s != null) { return s.Score; } else { return -1; } } set { listScores.Add(new Scores() { StuName = stuName, CourseId = courseId, Score = value }); } } //索引器重载,根据名字查找所有成绩 public List this[string stuName] { get { List tempList = listScores.FindAll(x => x.StuName == stuName); return tempList; } } } static void Main(string[] args) { //多参数索引器和索引器重载 FindScore fScore = new FindScore(); fScore["张三", 1] = 98; fScore["张三", 2] = 100; fScore["张三", 3] = 95; fScore["李四", 1] = 96; //查找 张三 课程编号2 的成绩 Console.WriteLine("李四 课程编号2 成绩为:" + fScore["李四", 1]); //查找所有张三的成绩 List listScores = fScore["张三"]; if (listScores.Count > 0) { foreach (Scores s in listScores) { Console.WriteLine(string.Format("张三 课程编号{0} 成绩为:{1}", s.CourseId, s.Score)); } } else { Console.WriteLine("无该学生成绩单"); } Console.ReadKey(); } ```