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

C# 靜態與非靜態欄位:記憶體模型、共享狀態與實例計數器實作

     編輯:關於C#

核心差異:儲存位置與生命週期

特性靜態欄位 (static)非靜態欄位 (instance)
儲存位置高頻堆, 隸屬類別物件實例內部, 隸屬實例
複製數量整個程式域僅一份每個實例各有一份
初始化時機類別首次存取前 (靜態建構子)每次 new 實例化時
存取方式類別名.欄位名實例.欄位名
共享狀態天然共享隔離,需額外機制共享

實戰範例:視窗實例計數器

using System;

public class Window {
    // 靜態欄位:追蹤所有視窗實例總數
    private static int _totalWindows = 0;
    public static int TotalWindows => _totalWindows;

    // 非靜態欄位:每個視窗獨有的標題與狀態
    public string Title { get; set; }
    public bool IsActive { get; private set; }
    public IntPtr Handle { get; private set; }

    // 唯讀實例編號:建構時指派,不可變
    public readonly int InstanceId;

    public Window(string title) {
        Title = title;
        InstanceId = ++_totalWindows; // 靜態欄位累加
        Handle = CreateWindowHandle(); // 假設建立原生視窗
        Console.WriteLine($"Window #{InstanceId} '{Title}' created. Total: {_totalWindows}");
    }

    ~Window() {
        _totalWindows--;
        DestroyWindowHandle(Handle);
        Console.WriteLine($"Window #{InstanceId} destroyed. Total: {_totalWindows}");
    }

    // 靜態方法:只能存取靜態成員
    public static string GetWindowTitle(Window w) => w?.Title ?? "null";

    // 非靜態方法:可存取靜態與非靜態成員
    public void Activate() {
        IsActive = true;
        Console.WriteLine($"Window #{InstanceId} activated. Total active: {_totalWindows}");
    }
}

執行結果範例

Window #1 'Main' created. Total: 1
Window #2 'Settings' created. Total: 2
Window #1 activated. Total active: 2
Window #2 destroyed. Total: 1
Window #1 destroyed. Total: 0

靜態方法存取限制解析


class Demo {
    static int _staticField = 10;
    int _instanceField = 20;

    static void StaticMethod() {
        _staticField = 5;    // OK
        // _instanceField = 5; // CS0120: 需要物件參考
    }

    void InstanceMethod() {
        _staticField = 5;    // OK
        _instanceField = 5;  // OK
    }
}

靜態方法無 this 參考,無法知道操作哪個實例的非靜態欄位,因此編譯器禁止直接存取。

設計指南:何時使用 static?

  • ✅ 真正的全域單一狀態:計數器、快取、設定值、單例實例。
  • ✅ 純函式輔助方法 (無副作用) 配合靜態欄位快取。
  • ❌ 請勿用於每個實例不同的資料 (如使用者名稱、視窗座標)。
  • ❌ 多執行緒環境下的可變靜態欄位 → 使用 ThreadStatic、AsyncLocal 或鎖定/無鎖集合。

記憶體洩漏風險

靜態欄位持有參考型別物件 → 該物件永遠不會被 GC 回收 (除非手動設為 null 或 AppDomain 卸載)。慎用靜態集合儲存大量資料,考慮 WeakReference 或定期清理。

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