C# 採單根繼承體系,所有類別隱含繼承 System.Object。本文深入探討類別宣告修飾符、實例與靜態成員存取規則、this 關鍵字三大用法、System.Object 七大虛擬/靜態方法契約(Equals/GetHashCode/ToString/GetType/Finalize/MemberwiseClone/ReferenceEquals)、值相等 vs 參考相等、ICloneable 深淺拷貝。
| 修飾符 | 語意 | 備註 |
|---|---|---|
public | 任意存取 | 非巢狀類別預設可見性 |
internal | 同組件存取 | 非巢狀類別預設(無修飾符時) |
protected | 本類別+衍生類別 | 僅限巢狀類別 |
protected internal | 同組件+衍生類別 | 僅限巢狀類別 |
private | 僅本類別 | 僅限巢狀類別 |
abstract | 不可實例化,可含抽象成員 | 不可與 sealed 共存 |
sealed | 禁止繼承 | 不可與 abstract 共存 |
static | 僅含靜態成員,不可實例化/繼承 | C# 2.0+,隱含 sealed |
partial | 跨檔案定義 | 編譯時合併 |
this 關鍵字obj.Method())。Type.Method()),不可透過實例(編譯錯誤 CS0176)。this 三大核心用法this.name = name;OtherService.Register(this);public int this[int i] { get => arr[i]; set => arr[i] = value; }注意:靜態方法/屬性/建構函式中不可使用 this。
public class Object {
// 靜態方法
public static bool Equals(object objA, object objB);
public static bool ReferenceEquals(object objA, object objB);
// 實例方法
public virtual bool Equals(object obj);
public virtual int GetHashCode();
public Type GetType();
public virtual string ToString();
protected virtual void Finalize(); // 見解構函式篇
protected object MemberwiseClone(); // 淺層拷貝
}
| 類型 | == 預設 | Equals 預設 | 建議覆寫 |
|---|---|---|---|
| 實值型別(struct/enum) | 無(需自行多載) | 值相等(ValueType 覆寫) | 覆寫 Equals + 多載 ==/!= + GetHashCode |
| 參考型別(class) | 參考相等 | 參考相等 | 覆寫 Equals 表達值相等 + GetHashCode;不建議 多載 == |
| string | 值相等(運算子多載) | 值相等 | 已正確實作 |
Equals/GetHashCode 覆寫鐵律Equals,**必須**覆寫 GetHashCode(相等物件哈希碼必相等)。GetHashCode 必須穩定(物件生命週期內不變),建議基於不可變欄位計算。
public override bool Equals(object obj) => obj is Person other && Id == other.Id;
public override int GetHashCode() => Id.GetHashCode(); // Id 為不可變識別碼
public static bool operator ==(Person a, Person b) => Equals(a, b);
public static bool operator !=(Person a, Person b) => !Equals(a, b);
ReferenceEquals:純參考相等檢查false(每次裝箱產生新物件)。GetType vs typeofobj.GetType():執行期取得實際型別(多型)。typeof(T):編譯期取得型別標記(泛型/靜態)。ToString:人類可讀表示MemberwiseClone:淺層拷貝ICloneable.Clone() 或序列化往返。
public readonly struct Point : IEquatable
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is Point p && Equals(p);
public override int GetHashCode() => HashCode.Combine(X, Y); // C# 7.3+ HashCode 結構體
public static bool operator ==(Point a, Point b) => a.Equals(b);
public static bool operator !=(Point a, Point b) => !a.Equals(b);
}
record 自動實作值相等
// C# 9+ record 自動產生:EqualityContract、Equals、GetHashCode、==/!=、ToString、with-expression
public record Person(string Name, int Age);
var p1 = new Person("Tom", 20);
var p2 = p1 with { Age = 21 }; // 非變更複製
Console.WriteLine(p1 == p2); // False(值相等比較所有屬性)
類別定義型別契約,物件承載執行期狀態。精通修飾符封裝邊界、善用 this 消除歧義、正確實作 Object 相等性契約(Equals/GetHashCode/ToString)、理解淺/深拷貝差異,並善用 record/readonly struct 現代語法簡化不可變資料模型,即能建構出語意清晰、行為正確、效能優異的 C# 型別系統。