索引器讓類別實例像陣列一樣用 obj[index] 存取內部資料,語法上以 this 關鍵字定義。
public class MyCollection
{
private int[] data = new int[10];
public int this[int index] // 索引器宣告
{
get => data[index];
set => data[index] = value;
}
}
// 使用
var c = new MyCollection();
c[3] = 99;
int v = c[3]; // 99
| 特性 | 說明 |
|---|---|
| 簽名 | 由參數數量與型別決定,不包含回傳型別或參數名 |
| 多載 | 同一類別可定義多個索引器,簽名必須不同 |
| 參數型別 | 不限於 int,可為 string、enum、多參數等 |
| 非變數 | 索引器值非變數,不可 ref/out 傳遞 |
| 命名 | 預設名稱 Item,可用 [IndexerName("Custom")] 變更 |
| 存取修飾詞 | get/set 可分別設定 public/private/protected |
public class TempRecord
{
private readonly float[] temps = { 56.2f, 56.7f, 56.5f, 56.9f, 58.8f,
61.3f, 65.9f, 62.1f, 59.2f, 57.5f };
public int Length => temps.Length;
public float this[int index]
{
get
{
if (index < 0 || index >= temps.Length)
throw new ArgumentOutOfRangeException(nameof(index));
return temps[index];
}
set
{
if (index < 0 || index >= temps.Length)
throw new ArgumentOutOfRangeException(nameof(index));
temps[index] = value;
}
}
}
public class DayCollection
{
private readonly string[] days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
public int this[string day]
{
get
{
for (int i = 0; i < days.Length; i++)
if (days[i].Equals(day, StringComparison.OrdinalIgnoreCase))
return i;
return -1; // 找不到
}
}
}
// 使用
var week = new DayCollection();
Console.WriteLine(week["Fri"]); // 5
Console.WriteLine(week["Made-up"]); // -1
public class Matrix
{
private readonly double[,] data;
public Matrix(int rows, int cols) => data = new double[rows, cols];
public double this[int row, int col]
{
get => data[row, col];
set => data[row, col] = value;
}
}
get/set 內部檢查邊界,拋出 ArgumentOutOfRangeException 或 ArgumentException。set 通常比 get 更嚴格(如 public get; private set;)。get 應為純查詢,不修改狀態。索引器是封裝集合存取的語法糖,善用多載、字串索引與參數驗證,能設計出直觀、安全的 API。