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

C# 欄位與屬性完全指南:readonly/const、屬性存取子、虛擬屬性與繼承行為

     編輯:關於C語言

欄位

分類與存取

  • 實例欄位:屬於物件,透過 obj.Field 存取。
  • 靜態欄位:屬於類別,透過 Type.Field 存取,不可 透過實例存取 (C# 強制)。

五種存取層級

public, protected, internal, protected internal, private。internal 限定於同一組件,配合 protected 可對衍生類別開放。

readonly vs const

特性constreadonly
初始化時機編譯期 (宣告時,常數運算式)執行期 (宣告或建構函式)
型別限制基本型別、string、enum、null 參考任意型別 (含陣列、物件)
靜態性隱含 static可 static 或實例
跨組件版本值內嵌呼叫端 IL,修改需重編譯所有參考組件執行期讀取,僅需重編譯定義組件

// const 範例
public const double PI = 3.14159;

// readonly 範例
public static readonly Color Black = new Color(0,0,0); // 需執行期建構
public readonly int[] Primes = {2,3,5,7}; // 實例唯讀陣列 (內容仍可修改,參考不可變)

欄位初始化機制

  • 編譯器預設將欄位初始化為預設值 (0, null, false...)。
  • 宣告時賦值 int x = 10; 會被編譯器移入建構函式最前端 (實例欄位 → 實例建構函式;靜態欄位 → 靜態建構函式)。
  • const 不屬於初始化,視為編譯期宏替換。

屬性

本質與語法

屬性 不佔用儲存空間,編譯為 get_PropertyName/set_PropertyName 兩個方法。提供封裝、驗證、延遲計算等能力。


class Person
{
    private string _name;
    public string Name
    {
        get => _name;
        set => _name = value ?? "Unknown"; // 驗證/預設值
    }
}

三種存取模式

  • 讀寫:同時有 get、set。
  • 唯讀:僅 get (不可在不同區塊分開宣告 get/set,會視為不同屬性)。
  • 唯寫:僅 set (罕見)。

屬性與繼承

  • 衍生類別以 new 隱藏基底屬性 (非多型)。
  • virtual/override/abstract/sealed 行為同方法。
  • 覆寫時可僅覆寫 get 或 set (另一存取子沿用基底)。
  • 透過 base.Property 呼叫基底實作。

abstract class A
{
    public virtual int X { get => 0; }
    public virtual int Y { get; set; }
    public abstract int Z { get; set; }
}
class B : A
{
    private int _z;
    public override int X => base.X + 1; // 唯讀覆寫
    public override int Y { set => base.Y = value < 0 ? 0 : value; } // 僅覆寫 set
    public override int Z { get => _z; set => _z = value; }
}

靜態屬性與外部屬性

  • static 屬性僅能存取靜態欄位。
  • extern 屬性配合 DllImport 實作 (罕見,通常用於 COM 互操作)。

最佳實踐

  1. 公開資料成員一律用屬性,保留未來加入驗證/通知/延遲載入的彈性。
  2. 自動實作屬性 (C# 3.0+):public int Age { get; set; } 編譯器自動產生支援欄位。
  3. 唯讀自動屬性 (C# 6.0+):public int Id { get; } = 42; 或建構函式賦值。
  4. init 存取子 (C# 9.0+):public string Name { get; init; } 允許物件初始化器賦值,其後不可變。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved