一、属性与索引器的核心区别
属性和索引器都是 C# 中用于封装数据访问的成员,但两者的使用场景并不相同。
- 属性(Property):一个对象的一个属性只对应一个值。若要存放多个值,就必须实例化多个对象,通常的做法是先实例化一个对象数组,再把每个实例化的对象赋给数组元素。
- 索引器(Indexer):一个对象对应的索引本质上是一个数组,可以存放多个数值或字符串。因此只需要实例化一个对象,就能存放并访问多个存储内容。
简单来说,属性是“一个对象一个值”,索引器是“一个对象多个值”。
二、示例代码的命名空间与引用
using System; using System.Collections.Generic; namespace aaa { // 后续示例类均定义在此命名空间内 }三、使用属性存放多个值
下面的arrClass通过构造方法和属性为字段赋值。由于一个对象只有一个Name属性值,要保存多个名字就必须创建多个对象。
public class arrClass { // 通过构造方法以及属性进行赋值 private string name; // 定义一个字段 public string Name { // 定义一个属性,通过属性来修改 name 字段的值 get { return name; } // 通过 Name 来获取 name 的值 set { name = value; } // 通过 Name 将值赋给 name 字段 } public arrClass(string name) { // 构造函数,实例化一个对象就执行一次 this.Name = name; // 把实例化对象带进来的参数 name 赋值给 Name 属性 } }四、使用索引器存放多个值
索引器使用this[int index]定义,可以让对象像数组一样通过下标访问内部数据。
public class indexer { // 创建一个索引器类 private string[] name = new string[10]; // 定义一个索引字段数组,也可以为 int[] public string this[int index] { // 定义索引器,string 是索引器类型,this 用来定义索引器 get { return name[index]; } // index 就是数组下标,获取 name[index] 的值,例如获取 name[3] 的值 set { name[index] = value; } // 将值赋给 name[index],例如把字符串 "dengyun" 赋给 name[3] } }索引器的元素类型也可以是int,下面再定义一个存放年龄的索引器类:
public class index1 { // 这里又创建了一个索引器类 private int[] age = new int[10]; // 索引器字段的值为 int 型 public int this[int index] { get { return age[index]; } // 获取 age[index] 的值 set { age[index] = value; } // 赋值 } }五、完整调用示例
下面的Main方法分别演示了索引器对象和属性对象数组的使用方式,并对比了两者在实例化数量上的差异。
public class MainClass { public static void Main(string[] args) // 主方法一定要为 static { indexer b = new indexer(); // 实例化一个索引对象 b,b 有点类似数组 b[10],这是索引器的特别之处 b[0] = "张三"; // 这里 b[index] 的 index 为 0,赋值 "张三" 给 b[0] b[1] = "李四"; // 赋值 "李四" 给 b[1] b[2] = "王五"; // 赋值 "王五" 给 b[2] Console.WriteLine(b[0]); // 输出 b[0],可以理解为数值就存放在数组 b 中 Console.WriteLine(b[1]); Console.WriteLine(b[2]); arrClass[] a = new arrClass[10]; // 实例化一组对象,即一整个数组的对象 a[0] = new arrClass("张三"); // 实例化一个对象,将它存入数组 a 中,存放位置是 a[0] a[1] = new arrClass("李四"); a[2] = new arrClass("王五"); Console.WriteLine(a[0].Name); // 通过对象访问自己的属性值来输出数值 Console.WriteLine(a[1].Name); Console.WriteLine(a[2].Name); index1 i = new index1(); // 和带属性的类相比,索引器类只需要实例化一个对象 i[0] = 18; i[1] = 22; i[9] = 9; // i[10] = 10; // 索引超出范围,会抛出 IndexOutOfRangeException Console.WriteLine(i[0]); Console.WriteLine(i[1]); Console.WriteLine(i[9]); Console.Read(); } }六、注意事项
- 索引器的下标从 0 开始,数组长度为 10 时,合法下标是 0 到 9,访问
i[10]会抛出IndexOutOfRangeException。 - 索引器本身不分配存储空间,真正的数据存放在它内部维护的数组字段中。
- 属性适合描述对象的单个特征,索引器适合描述对象内部的一组同类数据。
- 索引器可以重载,也可以使用非
int类型的下标,例如字符串键。