C#--索引器

索引器的行为的声明在某种程度上类似于属性(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# 中封装集合数据访问的重要工具,通过[]运算符让对象具备类似数组的访问体验,同时支持自定义读写逻辑(如索引验证、数据转换)。合理使用索引器可提升代码的可读性和灵活性,尤其在自定义集合类或数据容器时非常实用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值