首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 索引器 完整指南:語法、多載、介面應用與實戰模式

     編輯:關於C#

索引器 讓類別實例能像陣列或集合一樣透過方括號 [] 存取元素,是建立自訂集合、封裝資料存取邏輯的關鍵語法糖。本文完整解析索引器宣告、多參數、多載、介面定義、與屬性差異等核心觀念。

基本語法與屬性比較


// 屬性
public string Name { get; set; }

// 索引器:注意名稱固定為 this,參數在方括號內
public string this[int index]
{
    get { return $"索引 {index} 的值"; }
    set { /* 儲存邏輯 */ }
}

// 使用方式
var obj = new MyClass();
string val = obj[5];   // 呼叫 get
obj[5] = "新值";       // 呼叫 set

索引器 vs 屬性 差異總表

多參數與多型索引器


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)。
  • 文件註解:/// ... 針對索引參數說明。

常見錯誤

特性屬性索引器
識別名稱自訂名稱 (如 Name)固定為 this
參數列表無參數至少一個參數,置於 [] 內
多載方式名稱不同參數型別/數量不同 (簽章不同)
Static 支援可 static不可 static,必須為實例成員
介面宣告string Name { get; set; }string this[int i] { get; set; }
存取子參數get/set 無參數get/set 可存取索引參數
錯誤代碼原因修正
CS0111類別已包含相同簽章索引器檢查參數型別/數量是否重複
CS0054索引器存取子存取層級不一致get/set 皆為 public 或明確設定
CS0548介面索引器未實作實作類別需提供完整 get/set
邏輯錯誤set 內未實際儲存值確認後端儲存結構已更新

索引器是 C# 表達力豐富的特性之一,善用它能讓自訂類別擁有原生集合般的直覺操作體驗,特別適合領域模型中「以鍵存取值」的語意場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved