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

C# 索引子深度解析:語法本質、多型參數與實務應用模式

     編輯:關於C語言

索引子本質:帶參數的屬性

索引子讓類別實例支援 obj[index] 語法,本質是含參數的屬性。與陣列不同:

  • 參數型別不限於 int(可為 string、Tuple、enum 等)
  • 可多載(不同參數簽章)
  • 可定義 get/set 存取層級

經典範例:點集合與星期天氣


using System;

class Point {
    public double X, Y;
    public Point(double x, double y) { X = x; Y = y; }
    public override string ToString() => $"X: {X}, Y: {Y}";
}

class Points {
    private readonly Point[] _points;
    public Points(Point[] points) => _points = points;
    public int Count => _points.Length;

    // 整數索引子
    public Point this[int index] {
        get => _points[index];
        set => _points[index] = value;
    }
}

class WeatherOfWeek {
    // 整數索引:0=Sun, 5=Fri
    public string this[int index] {
        get {
            switch (index) {
                case 0: return "Today is cloudy!";
                case 5: return "Today is thundershower!";
                default: return "Today is fine!";
            }
        }
    }

    // 字串索引:星期名稱
    public string this[string day] {
        get {
            switch (day) {
                case "Sunday": return "Today is cloudy!";
                case "Friday": return "Today is thundershower!";
                default: return "Today is fine!";
            }
        }
    }
}

class Program {
    static void Main() {
        // Points 範例
        Point[] pts = new Point[10];
        for (int i = 0; i < pts.Length; i++) pts[i] = new Point(i, Math.Sin(i));
        Points ps = new Points(pts);
        for (int i = 0; i < ps.Count; i++) Console.WriteLine(ps[i]);

        // Weather 範例
        WeatherOfWeek w = new WeatherOfWeek();
        for (int i = 0; i < 6; i++) Console.WriteLine(w[i]);
        foreach (var d in new[] { "Sunday", "Monday", "Friday", "Saturday" })
            Console.WriteLine(w[d]);
        Console.ReadKey();
    }
}

進階特性總覽

特性語法範例應用場景
多參數public double this[int r, int c]矩陣、影像像素、棋盤
多載this[int i] + this[string key]雙模式存取(如 DataRow)
介面定義interface IMatrix { double this[int r, int c] { get; set; } }抽象矩陣運算
存取修飾public string this[int i] { get; private set; }唯讀對外、內部可寫
靜態索引子❌ C# 不支援改用靜態方法 Get(key)

實務設計模式

1. 設定/快取存取器


class AppSettings {
    private readonly Dictionary _data = new();
    public string this[string key] {
        get => _data.TryGetValue(key, out var v) ? v : null;
        set => _data[key] = value;
    }
}

2. 矩陣運算庫


readonly struct Matrix {
    private readonly double[,] _data;
    public Matrix(int rows, int cols) => _data = new double[rows, cols];
    public double this[int r, int c] {
        get => _data[r, c];
        set => _data[r, c] = value;
    }
    public int Rows => _data.GetLength(0);
    public int Cols => _data.GetLength(1);
}

3. 實作 IEnumerable 配合 foreach


class Points : IEnumerable {
    private readonly Point[] _points;
    public Point this[int i] => _points[i];
    public int Count => _points.Length;
    public IEnumerator GetEnumerator() => ((IEnumerable)_points).GetEnumerator();
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
}

最佳實踐清單

  1. 語意清晰:索引子應表達「存取元素」,避免在 get/set 埋藏複雜業務邏輯
  2. 參數驗證:越界拋 ArgumentOutOfRangeException,null 拋 ArgumentNullException
  3. 提供 Count/Length 配合迴圈
  4. 考慮實作 IEnumerable<T> 支援 LINQ 與 foreach
  5. 大型資料結構用 readonly struct + Span<T> 避免複製
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved