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

C# 類別核心基礎:建構函式、解構函式與方法參數傳遞

     編輯:關於C語言

第五章 類別:C# 程式的基石

沒有類別,連最簡單的 C# 程式都無法編譯。本章涵蓋建構函式/解構函式、方法參數傳遞、多型覆寫、方法遮蔽等核心主題。

5.1 建構函式與解構函式:物件的生與死

建構函式基本規則

  • 名稱與類別相同,無回傳型別
  • 預設為 public,若類別僅含靜態成員可標記 private 防止實例化
  • 編譯器會自動提供無參數預設建構函式(若未自訂)
  • 可多載:public TestClass(string name, int age) { ... }

資源釋放:解構函式 vs Dispose 模式

C# 解構函式 ~TestClass() 由垃圾收集器(GC)非同步呼叫,時機不可預測。若持有非受控資源(檔案控制代碼、資料庫連線、GDI+ 物件),必須實作顯式釋放方法:


public class TestClass : IDisposable
{
    private IntPtr _handle;  // 非受控資源

    // 顯式釋放 - 供呼叫端主動呼叫
    public void Dispose()
    {
        ReleaseResources();
        GC.SuppressFinalize(this);  // 告訴 GC 不需再呼叫解構函式
    }

    // 解構函式 - 防禦性程式,確保資源最終被釋放
    ~TestClass()
    {
        ReleaseResources();
    }

    private void ReleaseResources()
    {
        if (_handle != IntPtr.Zero)
        {
            CloseHandle(_handle);
            _handle = IntPtr.Zero;
        }
    }

    [DllImport("kernel32.dll")]
    private static extern bool CloseHandle(IntPtr hObject);
}

最佳實務:呼叫端使用 using 區塊確保 Dispose() 被呼叫:

using (var obj = new TestClass())
{
    // 使用資源
}  // 區塊結束自動呼叫 Dispose()

5.2 方法參數傳遞三部曲

5.2.1.1 輸入參數(傳值)

預設行為:建立引數副本,方法內修改不影響原變數。適用於值型別與參考型別的參考本身。


public int CalcSquare(int side) => side * side;
// 呼叫
var result = CalcSquare(25);  // 常數直接傳遞

5.2.1.2 參考參數(ref)

傳遞變數本身(位址),方法可修改原值。呼叫前必須初始化。


public void CalcSquare(ref int value)
{
    value *= value;  // 直接修改原變數
}

// 呼叫
int num = 20;  // 必須初始化
CalcSquare(ref num);  // num 變為 400

5.2.1.3 輸出參數(out)

專為「傳回額外結果」設計,呼叫前不需初始化,但方法必須在返回前賦值。


public void CalcSquare(int side, out int result)
{
    result = side * side;  // 必須賦值
}

// 呼叫
int squared;  // 無需初始化
CalcSquare(15, out squared);  // squared = 225
特性輸入 (預設)refout
呼叫端初始化不需必須不需
方法內讀取可可不可(未指派前)
方法內寫入僅影響副本影響原變數必須指派
適用場景單純輸入雙向資料流多重回傳值

5.2.2 方法覆寫:多型的核心

基類以 virtual 標記可覆寫方法,衍生類用 override 實作新行為。關鍵特性:即使透過基類參考呼叫,仍執行衍生類實作。


class Triangle
{
    public virtual double ComputeArea(int a, int b, int c)
    {
        double s = (a + b + c) / 2.0;
        return Math.Sqrt(s * (s - a) * (s - b) * (s - c));  // 海龍公式
    }
}

class RightAngledTriangle : Triangle
{
    public override double ComputeArea(int a, int b, int c)
    {
        // 驗證是否為直角三角形
        const double epsilon = 0.0001;
        if (Math.Abs(a * a + b * b - c * c) > epsilon)
            return base.ComputeArea(a, b, c);  // 呼叫基類實作

        return a * b / 2.0;  // 直角三角形面積公式
    }
}

關鍵觀念

  • base.ComputeArea(...) 可顯式呼叫基類實作,避免重複程式碼
  • 覆寫時不可變更存取層級(如基類 public,衍生類不可改 protected)
  • 非 virtual 方法預設不可覆寫,這比 C++ 預設 virtual 更安全、效能更好

本章小結

  • 建構函式初始化物件狀態;解構函式為非受控資源提供最後防線,但首選 IDisposable 模式
  • 三種參數傳遞模式各有用途:out 解決多重回傳,ref 實現雙向修改
  • virtual/override 實現執行期多型,base 關鍵字促進程式碼重用
  • 下一節將探討方法遮蔽(new)、屬性、索引子、事件等進階特性
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved