索引器的行为的声明在某种程度上类似于属性(property)。就像属性(property),您可使用 get 和 set 访问器来定义索引器。但是,属性返回或设置一个特定的数据成员,而索引器返回或设置对象实例的一个特定值。换句话说,它把实例数据分为更小的部分,并索引每个部分,获取或设置每个部分。
一、索引器的核心特点
-
语法上类似属性,但通过参数(如索引值)访问数据,而非固定名称。
-
支持重载(可定义多个参数类型的索引器,如
int索引、string键值索引)。 -
常用于封装类中的数组、列表(
List<T>)、字典(Dictionary<TKey, TValue>)等集合类型字段。
二、索引器的基本语法
public class 类名
{
// 私有集合字段(如数组、列表)
private T[] _data;
// 索引器定义:this[参数列表]
public 返回类型 this[参数类型 index]
{
get { /* 读取逻辑:返回对应索引的数据 */ }
set { /* 写入逻辑:设置对应索引的数据 */ }
}
}
-
this:表示当前类的实例,是索引器的标识。
-
参数列表:通常为
int类型(数组索引),也可自定义类型(如string键)。 -
value:写入时的参数(隐式变量,类型与索引器返回类型一致)。
三、索引器的具体示例
1.基础索引器:模拟数组访问
封装内部数组,通过索引器实现类似数组的读写:
public class StringCollection
{
// 私有字符串数组
private string[] _items = new string[5];
// 索引器:int类型索引,访问数组元素
public string this[int index]
{
get
{
// 索引合法性验证
if (index >= 0 && index < _items.Length)
return _items[index];
throw new IndexOutOfRangeException("索引超出范围");
}
set
{
if (index >= 0 && index < _items.Length)
_items[index] = value;
else
throw new IndexOutOfRangeException("索引超出范围");
}
}
}
// 使用示例
class Program
{
static void Main()
{
StringCollection collection = new StringCollection();
// 写入:通过索引器赋值
collection[0] = "Hello";
collection[1] = "World";
// 读取:通过索引器访问
Console.WriteLine(collection[0]); // 输出:Hello
Console.WriteLine(collection[1]); // 输出:World
// collection[5] = "Test"; // 抛出异常:索引超出范围
}
}
2.重载索引器:支持多种参数类型
定义多个索引器(如int索引、string键),实现灵活访问:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
public class StudentRegistry
{
// 内部存储:字典(键为学号)+ 列表(按顺序存储)
private Dictionary<string, Student> _studentDict = new Dictionary<string, Student>();
private List<Student> _studentList = new List<Student>();
// 索引器1:通过学号(string)访问
public Student this[string studentId]
{
get
{
if (_studentDict.ContainsKey(studentId))
return _studentDict[studentId];
throw new KeyNotFoundException("学号不存在");
}
set
{
if (!_studentDict.ContainsKey(studentId))
{
_studentDict.Add(studentId, value);
_studentList.Add(value);
}
else
_studentDict[studentId] = value;
}
}
// 索引器2:通过序号(int)访问
public Student this[int index]
{
get
{
if (index >= 0 && index < _studentList.Count)
return _studentList[index];
throw new IndexOutOfRangeException();
}
}
}
// 使用示例
class Program
{
static void Main()
{
StudentRegistry registry = new StudentRegistry();
// 通过学号索引写入
registry["001"] = new Student { Name = "张三", Age = 20 };
registry["002"] = new Student { Name = "李四", Age = 21 };
// 通过学号索引读取
Console.WriteLine(registry["001"].Name); // 输出:张三
// 通过序号索引读取
Console.WriteLine(registry[1].Name); // 输出:李四
}
}
3.只读索引器:仅提供get访问器
若只需读取数据,可定义只读索引器(省略 set):
public class ReadOnlyCollection
{
private int[] _data = { 1, 2, 3, 4, 5 };
// 只读索引器
public int this[int index]
{
get
{
if (index >= 0 && index < _data.Length)
return _data[index];
throw new IndexOutOfRangeException();
}
// 无set,外部无法写入
}
}
四、索引器与属性的区别
| 特性 | 索引器 | 属性 |
| 访问方式 | 通过[]+ 参数(如obj[0]) | 通过属性名(如obj.Name) |
| 参数 | 通过属性名(如obj.Name) | 无参数 |
| 重载 | 支持(不同参数类型) | 不支持(名称唯一) |
| 用途 | 访问集合 / 数组类型数据 | 访问单个字段 |
五、索引器的适用场景
-
封装类中的集合数据(数组、列表、字典),提供统一的访问接口。
-
模拟数组 / 容器行为(如自定义集合类、数据缓存)。
-
简化复杂数据结构的访问(如二维矩阵通过
matrix[row, col]访问)。
总结
索引器是 C# 中封装集合数据访问的重要工具,通过[]运算符让对象具备类似数组的访问体验,同时支持自定义读写逻辑(如索引验证、数据转换)。合理使用索引器可提升代码的可读性和灵活性,尤其在自定义集合类或数据容器时非常实用。
6496

被折叠的 条评论
为什么被折叠?



