C#屬性(Property)

2020-07-16 10:04:46
屬性(property)是一種用於存取物件或類的特性的成員。

屬性提供靈活的機制來讀取、編寫或計算私有欄位的值。

屬性提供了一種機制,它把讀取和寫入物件的某些特性與一些操作關聯起來。

可以像使用公共資料成員一樣使用屬性,但實際上屬性是稱為“存取器”的一種特殊方法,這使得資料在被輕鬆存取的同時,仍能提供方法的安全性和靈活性。

無參屬性

一般看來,常數和欄位已經足夠刻畫實際生活中物件的各種引數。實際上也確實是這樣。

屬性(property)是一種"高階欄位”,它可能帶有一個 getter 和一個 setter,它們保護屬性的值,使之不會被外部胡亂篡改。

和欄位相比,屬性實現了對成員的封裝。

Java 中有相似的概念(JavaBeans),它要求類中的成員都是私有的,並且提供一個 public 的 getter 和一個 setter,用於讓外界存取和修改私有欄位的值。

這兩個方法的名稱以 get 和 set 開頭,需要自己手寫。

在 C# 中,也可以通過欄位和一對讀寫方法,自己手動實現屬性:
class A
{
    private int c;
    public int getC()
    {
        return c;
    }
    public void setC(int value)
    {
        c = value;
    }
}
在這裡的私有欄位稱為支援欄位(Backing Field)。

不過,這樣做有兩個明顯缺點,一是必須手打這些程式碼;二是在存取屬性時,必須呼叫方法,而不能直接使用點號加屬性名。

CLR 提供了稱為屬性的機制,解決了這兩個缺點。下面的寫法是經過簡化了的寫法:

private int c { get;  set;  }

如果不想屬性有任何特殊行為,從 C# 3 開始,可以使用簡易語法get; set;

這樣建立的屬性叫做自動實現的屬性。另外,我們可以直接通過 A.c 存取屬性,而非使用 A.getCA.setC 方法了。

實際上,無參屬性僅僅是語法糖。通過編譯之後使用 iladsm 檢視,我們可以發現,編譯器自動為我們生成了 get_c 和 sct_c 方法,以及一個支援欄位 <c>k_BackingField,如下圖所示。

自動實現的屬性