C#索引器最简语法为:public string this[int index] { get { return _items[index]; } set { _items[index] = value; } },本质是带this的特殊属性,无返回类型声明、无方法名,value仅在set中有效。

索引器怎么写,最简语法长什么样
C#索引器本质是带 this 关键字的特殊属性,不是方法也不是字段。它让类实例能像数组一样用方括号取值或赋值。
最基础写法必须包含:访问修饰符、this、方括号内的参数(至少一个)、get 和/或 set 访问器:
public string this[int index]
{
get { return _items[index]; }
set { _items[index] = value; }
}
注意三点:
-
this后面的参数类型不能是void,但可以是任意类型(如string、Guid),不局限于int - 没有返回类型声明在
this前面——返回类型写在this之前(比如上面的string) - 不能有方法名;
this就是它的“名字”
为什么 get 里用 value 会编译失败
常见错误:在 get 访问器里误写 value,比如 return value; —— 这会报错 CS0103: The name 'value' does not exist in the current context。
value 是 set 访问器的隐式参数,只在 set 里有效;get 的职责是返回值,不接收输入。
正确做法:
-
get里只做读取和返回,例如return _data[index]; -
set里用value接收传入的值,例如_data[index] = value; - 如果只读,就只写
get;如果只写(极少),就只写set(此时set里仍可用value)
支持多个参数或非 int 类型索引时要注意什么
索引器可以重载,比如同时支持 int 和 string 索引,但不能仅靠返回类型区分——这点和普通方法重载规则一致。
多参数索引器合法,但语义要清晰,避免滥用:
public Person this[string firstName, string lastName]
{
get { return _people.FirstOrDefault(p => p.FirstName == firstName && p.LastName == lastName); }
}
注意事项:
- 参数顺序会影响调用方式,
obj["Tom", "Lee"]不能写成obj["Lee", "Tom"] - 性能敏感场景慎用多参数索引器,尤其是涉及 LINQ 查询时,
FirstOrDefault是 O(n) 操作 - 别为了“看起来高级”而用字符串索引代替字典——直接用
Dictionary更合适、更高效
继承和接口中使用索引器的坑
接口可以定义索引器,但只能声明 get/set,不能实现;类实现时,访问器修饰符不能比接口更严格(比如接口没写 get,实现类也不能只写 set)。
继承时,子类用 base 调用父类索引器是允许的,但容易忽略边界检查重复问题:
- 父类索引器已做
index = _count检查,子类重写时若再检查一遍,逻辑冗余 - 若子类想扩展行为(比如日志),应在
get/set内部调用base[index],而不是重新实现整个逻辑 - 索引器不能被
virtual/override修饰——它本身是属性,要用virtual必须显式写在this[...]前面,且派生类用override匹配
真正容易被忽略的是:索引器不参与隐式转换,也不触发运算符重载。它就是语法糖,背后仍是属性访问机制。别指望 myList[5] += 1 自动调用 get + set 组合——它等价于 myList[5] = myList[5] + 1,会调两次索引器,中间值可能被其他线程改掉。










