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

C# 索引器與運算子多載實戰:打造直觀的集合存取與數學型別

     編輯:關於C語言

索引器

語法與本質

索引器讓物件支援陣列式存取 obj[index]。關鍵字 this 替代屬性名,可帶參數列表。編譯為 get_Item/set_Item 方法。


class MyCollection
{
    private object[] _data = new object[100];
    public object this[int index]
    {
        get => _data[index];
        set => _data[index] = value;
    }
}
// 使用
var c = new MyCollection();
c[0] = "Hello";
Console.WriteLine(c[0]);

特性規則

  • 至少一個參數,參數只能為 傳值 (不可 ref/out)。
  • 參數型別任意 (可多參數,如 this[int x, int y])。
  • 多載依參數簽名區分 (同方法多載)。
  • 不可 static (屬於實例)。
  • 存取修飾詞、virtual/override/sealed/abstract/extern 同方法。
  • 覆寫時以 base[index] 呼叫基底實作。

實戰範例:位元組陣列的位元級存取


class BitArray
{
    private readonly int[] _bits;
    public int Length { get; }
    public BitArray(int length)
    {
        if (length < 0) throw new ArgumentOutOfRangeException();
        _bits = new int[(length - 1 >> 5) + 1];
        Length = length;
    }
    public bool this[int index]
    {
        get
        {
            if (index < 0 || index >= Length) throw new IndexOutOfRangeException();
            return (_bits[index >> 5] & (1 << index)) != 0;
        }
        set
        {
            if (index < 0 || index >= Length) throw new IndexOutOfRangeException();
            if (value) _bits[index >> 5] |= 1 << index;
            else _bits[index >> 5] &= ~(1 << index);
        }
    }
}
// 使用:10 位元陣列,偶數位設 true
var bits = new BitArray(10);
for (int i = 0; i < 10; i++) bits[i] = i % 2 == 0;
for (int i = 0; i < 10; i++) Console.Write(bits[i] + " "); // True False True False ...

優勢:以 int[] 儲存 32 個布林值,記憶體效率提升 32 倍,介面仍如 bool[] 般直觀。

運算子多載

三大類別與可多載清單

類別運算子
一元+ - ! ~ ++ -- true false
二元+ - * / % & | ^ << >> == != > < >= <=
轉換implicit (隱式)、explicit (顯式)

規則:必須 public static,參數為傳值,回傳型別視運算子而定。不可 virtual/override/sealed/abstract。父類別多載運算子被繼承但不可覆寫。

一元運算子範例:複數


struct Complex
{
    public double Re, Im;
    public Complex(double re, double im) { Re = re; Im = im; }

    public static Complex operator +(Complex a, Complex b) => new Complex(a.Re + b.Re, a.Im + b.Im);
    public static Complex operator -(Complex a) => new Complex(-a.Re, -a.Im); // 一元負號
    public static Complex operator ++(Complex a) => new Complex(a.Re + 1, a.Im + 1); // 前置/後置皆用此簽章

    public override string ToString() => $"{Re} + {Im}i";
}

static void Main()
{
    var a = new Complex(3,4);
    var b = new Complex(5,6);
    Console.WriteLine(-a);      // -3 + -4i
    Console.WriteLine(a + b);   // 8 + 10i
    Console.WriteLine(a++);     // 3 + 4i (後置傳回舊值)
    Console.WriteLine(a);       // 4 + 5i
    Console.WriteLine(++a);     // 5 + 6i (前置傳回新值)
}

關鍵點:++/-- 必須回傳 新實例 (不可修改參數),前置/後置語意由編譯器處理 (前置傳回運算後值,後置傳回運算前值)。

二元運算子規則

  • 兩個參數,至少一個 為宣告型別。
  • ==/!=、>/<、>=/<= 必須成對宣告。
  • 參數型別/順序不同可構成多載。

轉換運算子:Digit 與 byte 互轉


struct Digit
{
    private readonly byte _value;
    public Digit(byte v) { if (v > 9) throw new ArgumentException(); _value = v; }

    // 隱式轉換:Digit → byte (無資訊遺失)
    public static implicit operator byte(Digit d) => d._value;

    // 顯式轉換:byte → Digit (可能丟失資訊/拋出例外)
    public static explicit operator Digit(byte b) => new Digit(b);
}

// 使用
Digit d = 5;          // 隱式 byte→Digit? 不行,需顯式:Digit d = (Digit)5;
byte b = d;           // 隱式 Digit→byte OK
Digit d2 = (Digit)10; // 執行期拋出 ArgumentException

設計原則:資訊不遺失 → implicit;可能遺失/例外 → explicit。同參數型別不可同時宣告兩者。

總結

索引器與運算子多載皆為「方法的語意包裝」,旨在提供 領域自然的操作介面。善用它們能讓 API 更直觀 (如 matrix[i,j]、v1 + v2、(Digit)b),但濫用會導致語意模糊,僅在型別行為符合直覺數學/集合語意時使用。

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