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

C# 類別與物件核心概念:修飾符、this、System.Object 契約與單根繼承

     編輯:關於C#

前言:類別是藍圖,物件是實體

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 關鍵字

2.1 實例 vs 靜態成員存取規則

  • 實例成員:只能透過實例存取(obj.Method())。
  • 靜態成員:只能透過類型名稱存取(Type.Method()),不可透過實例(編譯錯誤 CS0176)。

2.2 this 三大核心用法

  1. 消除名稱遮蓋(建構函式/設值器):this.name = name;
  2. 傳遞當前實例:OtherService.Register(this);
  3. 索引器宣告:public int this[int i] { get => arr[i]; set => arr[i] = value; }

注意:靜態方法/屬性/建構函式中不可使用 this。

三、System.Object:所有類別的共同祖先

3.1 七大核心成員


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();     // 淺層拷貝
}

3.2 相等性比較:值相等 vs 參考相等

類型== 預設Equals 預設建議覆寫
實值型別(struct/enum)無(需自行多載)值相等(ValueType 覆寫)覆寫 Equals + 多載 ==/!= + GetHashCode
參考型別(class)參考相等參考相等覆寫 Equals 表達值相等 + GetHashCode;不建議 多載 ==
string值相等(運算子多載)值相等已正確實作

3.3 Equals/GetHashCode 覆寫鐵律

  1. 若覆寫 Equals,**必須**覆寫 GetHashCode(相等物件哈希碼必相等)。
  2. GetHashCode 必須穩定(物件生命週期內不變),建議基於不可變欄位計算。
  3. 實作範本:

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);

3.4 ReferenceEquals:純參考相等檢查

  • 靜態方法,不可覆寫。
  • 實值型別經裝箱後永遠回傳 false(每次裝箱產生新物件)。
  • 用於需確認「是否為同一個物件實例」的低層邏輯。

3.5 GetType vs typeof

  • obj.GetType():執行期取得實際型別(多型)。
  • typeof(T):編譯期取得型別標記(泛型/靜態)。

3.6 ToString:人類可讀表示

  • 預設回傳完整型別名稱。
  • 強烈建議覆寫提供領域意義字串(除錯、日誌、序列化)。

3.7 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);
}

五、現代 C#: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# 型別系統。

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