C#索引器是类或结构的一种特殊成员,它让实例可以像数组一样通过方括号加索引的方式访问内部存储的元素,不需要额外调用方法就能完成取值和赋值操作,非常适合封装内部集合或自定义数据容器的场景。

C#索引器的基本语法
索引器的定义和属性类似,但是没有名称,使用this关键字作为标识,后面跟着方括号包裹的索引参数。基本语法结构如下:
// 索引器基本语法
访问修饰符 返回值类型 this[索引参数类型 索引参数名]
{
get
{
// 根据索引返回对应的值
}
set
{
// 根据索引设置对应的值,value是隐式参数
}
}
索引器可以只有get访问器(只读索引器),也可以只有set访问器(只写索引器),和属性的访问器规则一致。
自定义索引器实现示例
下面通过一个自定义的整数列表类来演示如何实现自定义索引器,这个类内部用数组存储数据,对外提供索引访问能力:
using System;
namespace IndexerDemo
{
// 自定义整数列表类
public class MyIntList
{
// 内部存储数组
private int[] _data;
// 数组实际存储的元素数量
private int _count;
// 构造函数,初始化容量
public MyIntList(int capacity)
{
_data = new int[capacity];
_count = 0;
}
// 添加元素的方法
public void Add(int item)
{
if (_count >= _data.Length)
{
// 容量不足时扩容,这里简单处理为抛出异常
throw new InvalidOperationException("列表容量已满");
}
_data[_count] = item;
_count++;
}
// 自定义索引器,索引为int类型,返回int类型
public int this[int index]
{
get
{
// 索引校验
if (index < 0 || index >= _count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
return _data[index];
}
set
{
if (index < 0 || index >= _count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
_data[index] = value;
}
}
// 获取当前元素数量
public int Count
{
get { return _count; }
}
}
class Program
{
static void Main(string[] args)
{
MyIntList list = new MyIntList(5);
list.Add(10);
list.Add(20);
list.Add(30);
// 使用索引器取值
Console.WriteLine(list[0]); // 输出10
Console.WriteLine(list[1]); // 输出20
// 使用索引器赋值
list[2] = 35;
Console.WriteLine(list[2]); // 输出35
// 遍历所有元素
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine($"索引{i}的值:{list[i]}");
}
}
}
}
索引器的进阶用法
索引器重载
和普通方法一样,索引器也支持重载,只要参数列表的类型或数量不同即可。比如我们可以给上面的MyIntList类添加一个字符串类型的索引器,通过元素值查找对应的索引:
// 重载索引器,参数为string类型,返回int类型(元素值对应的索引)
public int this[string itemValue]
{
get
{
for (int i = 0; i < _count; i++)
{
if (_data[i].ToString() == itemValue)
{
return i;
}
}
return -1; // 没找到返回-1
}
}
使用时可以直接通过字符串值查找索引:
// 调用重载的索引器 int index = list["20"]; Console.WriteLine(index); // 输出1
在接口中定义索引器
索引器也可以在接口中声明,实现该接口的类必须实现对应的索引器。示例如下:
// 定义包含索引器的接口
public interface IMyCollection<T>
{
T this[int index] { get; set; }
int Count { get; }
}
// 实现接口的类
public class MyStringCollection : IMyCollection<string>
{
private string[] _items;
private int _count;
public MyStringCollection(int capacity)
{
_items = new string[capacity];
_count = 0;
}
public void Add(string item)
{
if (_count >= _items.Length)
{
throw new InvalidOperationException("容量已满");
}
_items[_count] = item;
_count++;
}
// 实现接口的索引器
public string this[int index]
{
get
{
if (index < 0 || index >= _count)
{
throw new IndexOutOfRangeException();
}
return _items[index];
}
set
{
if (index < 0 || index >= _count)
{
throw new IndexOutOfRangeException();
}
_items[index] = value;
}
}
public int Count
{
get { return _count; }
}
}
索引器的使用注意事项
- 索引器的参数类型不限于int,可以是任意类型,比如string、自定义类等,只要符合重载规则即可。
- 索引器不能作为ref或out参数传递,这是和数组索引的区别之一。
- 索引器内部一定要做索引合法性校验,避免访问越界导致程序异常。
- 如果类内部没有存储集合结构,不建议强行实现索引器,避免造成语义混淆。
合理使用索引器可以让自定义类的使用方式更符合开发者的直觉,尤其是封装集合类、配置类、缓存类等场景时,索引器能大幅简化调用方的代码逻辑。