c# 索引器是什么

来源:这里教程网 时间:2026-02-21 17:39:21 作者:

C# 索引器就是让你的对象能像数组一样被方括号

[]
访问的机制——它不是语法糖,而是编译器生成真实方法(
get_Item
/
set_Item
)的正式语言特性。

索引器本质:带参数的 this 属性

它长得像属性,但没有名字,用

this[...]
声明;行为像方法,但调用时不用括号,直接写
obj[0]
obj["key"]
。关键点:

this
是强制关键字,不可省略或替换成其他标识符
参数类型任意:支持
int
string
Index
Range
,甚至自定义类型
不能是静态成员,必须是实例级(
static this[int i] {...}
❌ 不合法)
不归类为变量,所以不能传给
ref
out
参数

为什么用索引器而不是公开内部数组?

封装性 + 安全控制是核心动机。比如你有个温度记录类

TempRecord
,内部存着
float[] temps
,但你不希望用户绕过校验直接操作数组:

public class TempRecord
{
    private float[] temps = new float[24];
<pre class='brush:php;toolbar:false;'>public float this[int hour]
{
    get
    {
        if (hour < 0 || hour >= 24)
            throw new ArgumentOutOfRangeException(nameof(hour));
        return temps[hour];
    }
    set
    {
        if (value < -100 || value > 100)
            throw new ArgumentException("温度超出合理范围");
        temps[hour] = value;
    }
}

}

这样调用

record[25] = 36.5f
就会立刻抛异常,而直接访问
record.temps[25]
可能静默越界或引发后续逻辑错误。

常见踩坑:重载冲突与接口实现

多个索引器共存没问题,但参数签名必须严格区分;接口中声明索引器时,显式实现容易出错:

两个索引器参数类型相同但顺序不同(如
this[string, int]
this[int, string]
)✅ 允许重载
只定义
get
没有
set
→ 只读索引器(
collection[0] = "x"
编译报错)
实现接口索引器时,若类同时实现多个含同签名索引器的接口,必须用显式语法:
string IEmployee.this[int i] { get; set; }
别在索引器里做耗时操作(如查数据库),因为
obj[i]
看起来像普通访问,实则可能很重

支持现代 C# 特性:Index 和 Range

C# 8+ 可直接用

^
(末尾索引)和
..
(范围)语法,前提是索引器明确支持:

public string this[Index index] => words[index];
public string[] this[Range range] => words[range];

调用时就能写

sentence[^1]
sentence[1..3]
。注意:这依赖底层数组/集合本身支持
Index
/
Range
,否则运行时报错,不是编译期检查。

索引器真正难的不是写法,而是想清楚“这个访问是否该暴露”以及“边界和副作用怎么兜住”——它把隐式数组访问变成了显式契约,一旦加了,就得对每次

[...]
调用负责。

相关推荐