索引器
使用类似数组的语法访问对象。
索引器 是 CoddyKit 上的免费 C# Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
什么是索引器
索引器允许您使用 [ ] 语法访问对象,就像访问数组一样。您可以通过 this[...] 定义索引器。它非常适合类似集合的类。
using System;
class Week
{
private string[] _days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
public string this[int index] => _days[index];
}
class Program
{
static void Main()
{
var w = new Week();
Console.WriteLine(w[0]);
Console.WriteLine(w[6]);
}
}索引器语法
索引器看起来像属性,但会使用 this,并在方括号中接收参数列表。它包含 get,也可以选择包含 set。
using System;
class Scores
{
private int[] _data = new int[5];
public int this[int i]
{
get { return _data[i]; }
set { _data[i] = value; }
}
}
class Program
{
static void Main()
{
var s = new Scores();
s[0] = 90;
s[1] = 75;
Console.WriteLine(s[0] + ", " + s[1]);
}
}通过索引器读写
同时提供获取器和设置器后,您就可以像操作数组一样赋值和读取元素,同时由类控制底层存储。
using System;
class Grid
{
private int[] _cells = new int[3];
public int this[int i]
{
get => _cells[i];
set => _cells[i] = value;
}
}
class Program
{
static void Main()
{
var g = new Grid();
for (int i = 0; i < 3; i++) g[i] = i * 10;
Console.WriteLine(g[0] + ", " + g[1] + ", " + g[2]);
}
}在索引器中进行验证
索引器本质上也是代码,因此您可以验证索引,并在访问超出范围时抛出清晰的错误。
using System;
class SafeList
{
private int[] _data = new int[3];
public int this[int i]
{
get
{
if (i < 0 || i >= _data.Length)
throw new IndexOutOfRangeException("Bad index: " + i);
return _data[i];
}
set { _data[i] = value; }
}
}
class Program
{
static void Main()
{
var list = new SafeList();
list[1] = 42;
Console.WriteLine(list[1]);
}
}字符串键索引器
索引器参数并不局限于 int。使用 string 键可以让您的类变成类似字典的查找结构。
using System;
using System.Collections.Generic;
class Config
{
private Dictionary<string, string> _map = new Dictionary<string, string>();
public string this[string key]
{
get => _map.ContainsKey(key) ? _map[key] : "(none)";
set => _map[key] = value;
}
}
class Program
{
static void Main()
{
var c = new Config();
c["theme"] = "dark";
Console.WriteLine(c["theme"]);
Console.WriteLine(c["missing"]);
}
}多个参数
索引器可以接收多个参数,非常适合矩阵或二维网格,例如使用 matrix[row, col] 进行访问。
using System;
class Matrix
{
private int[,] _data = new int[2, 2];
public int this[int row, int col]
{
get => _data[row, col];
set => _data[row, col] = value;
}
}
class Program
{
static void Main()
{
var m = new Matrix();
m[0, 0] = 1;
m[1, 1] = 9;
Console.WriteLine(m[0, 0] + ", " + m[1, 1]);
}
}只读索引器
省略设置器即可创建只读索引器,在公开数据的同时不允许外部修改。
using System;
class Fibonacci
{
public int this[int n]
{
get
{
int a = 0, bv = 1;
for (int i = 0; i < n; i++)
{
int t = a + bv;
a = bv;
bv = t;
}
return a;
}
}
}
class Program
{
static void Main()
{
var fib = new Fibonacci();
Console.WriteLine(fib[7]);
}
}索引器与属性的比较
属性通过名称访问(obj.Name),索引器通过键访问(obj[key])。当对象表现得像集合时,请使用索引器。
using System;
class Inventory
{
private int[] _stock = new int[4];
public int Total => _stock.Length; // property
public int this[int slot] // indexer
{
get => _stock[slot];
set => _stock[slot] = value;
}
}
class Program
{
static void Main()
{
var inv = new Inventory();
inv[2] = 15;
Console.WriteLine("Slot 2: " + inv[2] + ", Total slots: " + inv.Total);
}
}重载索引器
您可以使用不同的参数类型定义多个索引器,编译器会选择相匹配的索引器。
using System;
using System.Collections.Generic;
class People
{
private List<string> _names = new List<string> { "Ann", "Bob", "Cara" };
public string this[int i] => _names[i];
public int this[string name] => _names.IndexOf(name);
}
class Program
{
static void Main()
{
var p = new People();
Console.WriteLine(p[1]);
Console.WriteLine(p["Cara"]);
}
}遍历带索引的对象
将索引器与计数属性结合,就可以自然地循环遍历自定义集合。
using System;
class Ring
{
private int[] _data = { 10, 20, 30 };
public int Count => _data.Length;
public int this[int i] => _data[i % _data.Length];
}
class Program
{
static void Main()
{
var ring = new Ring();
for (int i = 0; i < 5; i++)
Console.Write(ring[i] + " ");
Console.WriteLine();
}
}综合运用
索引器可以让包装类表现得像原生集合,并使用熟悉的方括号语法隐藏存储细节。
using System;
using System.Collections.Generic;
class Phonebook
{
private Dictionary<string, string> _book = new Dictionary<string, string>();
public string this[string name]
{
get => _book.TryGetValue(name, out var num) ? num : "unknown";
set => _book[name] = value;
}
}
class Program
{
static void Main()
{
var pb = new Phonebook();
pb["Alice"] = "555-1234";
Console.WriteLine("Alice: " + pb["Alice"]);
Console.WriteLine("Zed: " + pb["Zed"]);
}
}快速检查
请检验您对索引器的理解。
回顾
索引器使用 this[...] 为类提供类似数组的访问方式。它支持 get/set、任意参数类型(int、字符串、多个参数)、验证、重载以及只读形式。类似集合的类适合使用索引器;对于各不相同的属性,请使用命名属性。
using System;
class Demo
{
private int[] _v = new int[3];
public int this[int i]
{
get => _v[i];
set => _v[i] = value;
}
}
class Program
{
static void Main()
{
var d = new Demo();
d[0] = 100;
Console.WriteLine(d[0]);
}
}常见问题解答
「索引器」课时是免费的吗?
是的 — 「索引器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「索引器」这节课中我会学到什么?
使用类似数组的语法访问对象。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「索引器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。