| 特性 | 屬性 | 索引器 |
| 識別名稱 | 自訂名稱 (如 Name) | 固定為 this |
| 參數列表 | 無參數 | 至少一個參數,置於 [] 內 |
| 多載方式 | 名稱不同 | 參數型別/數量不同 (簽章不同) |
| Static 支援 | 可 static | 不可 static,必須為實例成員 |
| 介面宣告 | string Name { get; set; } | string this[int i] { get; set; } |
| 存取子參數 | get/set 無參數 | get/set 可存取索引參數 |
多參數與多型索引器
public class Matrix
{
private double[,] data = new double[10, 10];
// 雙參數索引器
public double this[int row, int col]
{
get => data[row, col];
set => data[row, col] = value;
}
// 多載:字串鍵值查找
public double this[string key]
{
get => data[ParseKey(key)];
set => data[ParseKey(key)] = value;
}
private (int, int) ParseKey(string key) => /* 解析邏輯 */;
}
介面中定義索引器
public interface IKeyValueStore
{
TValue this[TKey key] { get; set; }
// 等同於:
// TValue Get(TKey key);
// void Set(TKey key, TValue value);
}
public class DictionaryStore : IKeyValueStore
{
private Dictionary dict = new();
public TValue this[TKey key]
{
get => dict.TryGetValue(key, out var v) ? v : default;
set => dict[key] = value;
}
}
.NET 基底類別庫中 IList<T>、IDictionary<TKey, TValue> 皆宣告索引器,統一集合存取介面。
實戰模式:安全存取、計算屬性、動態物件
1. 邊界檢查與預設值
public class SafeArray
{
private T[] items;
public T this[int i]
{
get => (i >= 0 && i < items.Length) ? items[i] : default;
set { if (i >= 0 && i < items.Length) items[i] = value; }
}
}
2. 計算型索引器 (無後端儲存)
public class Fibonacci
{
public long this[int n]
{
get
{
if (n < 0) throw new ArgumentOutOfRangeException();
long a = 0, b = 1;
for (int i = 0; i < n; i++) (a, b) = (b, a + b);
return a;
}
}
}
// 使用:var fib = new Fibonacci(); Console.WriteLine(fib[10]); // 55
3. 動態物件搭配 DynamicObject
public class DynamicBag : System.Dynamic.DynamicObject
{
private Dictionary bag = new();
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1 && indexes[0] is string key)
return bag.TryGetValue(key, out result);
result = null; return false;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes.Length == 1 && indexes[0] is string key)
{ bag[key] = value; return true; }
return false;
}
}
// 使用:dynamic d = new DynamicBag(); d["name"] = "Tom"; Console.WriteLine(d["name"]);
最佳實務與效能考量
- 唯讀索引器:僅實作
get,適用不可變集合。
- 避免昂貴運算:
get 應為 O(1) 或極快,複雜計算改用方法 (如 Compute()) 明確語意。
- 參數驗證:
get/set 內部驗證索引合法性,拋出 ArgumentOutOfRangeException 或 KeyNotFoundException。
- 命名慣例:單一參數慣用
index、key;多參數用具體語意名 (row, col)。
- 文件註解:
/// ... 針對索引參數說明。
常見錯誤
| 錯誤代碼 | 原因 | 修正 |
| CS0111 | 類別已包含相同簽章索引器 | 檢查參數型別/數量是否重複 |
| CS0054 | 索引器存取子存取層級不一致 | get/set 皆為 public 或明確設定 |
| CS0548 | 介面索引器未實作 | 實作類別需提供完整 get/set |
| 邏輯錯誤 | set 內未實際儲存值 | 確認後端儲存結構已更新 |
索引器是 C# 表達力豐富的特性之一,善用它能讓自訂類別擁有原生集合般的直覺操作體驗,特別適合領域模型中「以鍵存取值」的語意場景。
- 上一篇文章: C# 網路程式設計入門:TCP 同步阻塞式 Client/Server 完整實作
- 下一篇文章: C# 例外處理機制與自訂例外類別完整實作指南
Copyright ©
程式碼之家 All Rights Reserved