2010-03-29 26 views

回答

29

一個不可變型是一種類型的,其中它的屬性只能在初始化時被設置。一旦創建了一個對象,什麼都不能改變。一個不可變屬性只是一個只讀屬性。

在以下示例中,ImmutableType是不可變類型,其中一個屬性爲Test。測試是隻讀屬性。它只能在施工中設置。

class ImmutableType 
{ 
    private readonly string _test; 
    public string Test 
    { 
     get { return _test; } 
    } 

    public ImmutableType(string test) 
    { 
     _test = test; 
    } 
} 

參見:The Wikipedia article,並且some StackOverflow questions的話題。

+4

您可以通過以只讀方式爲_test加前綴來針對將來的類更改實施不變性。唉,可悲的是在C#中沒有不可變的自動實現的屬性。 – 2010-03-29 12:03:47

+0

@Sam:謝謝,更新了這個例子。 – fretje 2010-03-29 12:07:50

+3

當你的屬性是引用類型時,這會有點棘手。那麼,不可變定義的定義可以被解釋爲*引用*是不可變的,或者*對象圖*是不可變的(取決於您的需要,但通常它是後者 - 請參閱Wiki文章)。 – 2010-03-29 12:24:34

4

fretje是正確的。最流行的不可變類型的示例是C#中的string對象。這是StringBuilder存在的全部原因。

3

除了上面的@ fretje的回答,在C#6和更高版本中,getter-only auto properties現在已經實現,它允許不變的自動屬性,而不需要額外的顯式private readonly支持字段。等效代碼將被縮寫爲:

class ImmutableType 
{ 
    public string Test 
    { 
     get; // No Set at all, not even a private set. 
    } 

    public ImmutableType(string test) 
    { 
     Test = test; // The compiler understands this and initializes the backing field 
    } 
} 

注意private set(最接近不變性能得到早期版本的C#中使用自動屬性)只能從同一類中提供了變化的限制封裝的財產,因而不是真正一成不變:

public string Test 
{ 
    get; 
    private set; // Not immutable, since this is still mutable from within the class 
} 

更多關於永恆

正如其他人所說,一個immutable Property是一個屬性一旦設置就不能改變。 「唯一值」的設置通常在構造函數中完成。

immutable Type是一種所有(外部可見)屬性和字段都是不可變的類型 - 例如最初爲C#7 (hopefully now 8)計劃的「記錄」類型本來就是不可變的類型。其他不可變類型的例子是Tuples,以及全部anonymous classes

不可變字段應該與C#中的readonly關鍵字限定 - 這是由編譯器執行,以確保沒有其他代碼試圖改變的構造以外的領域。

只要有可能,字段,變量和屬性的不變性被認爲是好的做法,因爲這大大減少了bug的表面積(因爲字段代表對象的狀態,防止字段的改變減少了狀態的數量)。

不變性的好處是特別重要的多線程程序,其中兩個或多個線程同時訪問同一個對象。由於多個併發讀取線程可以安全地訪問字段或屬性的值,因此程序員無需擔心與其他線程更改字段有關的線程安全問題。

不變性的一個共同的缺點與由多個組成物體的複雜對象處理時,是整個圖形需要「一次性」,這可導致凌亂的代碼來構建。這裏常見的解決方案是使用Builder pattern作爲腳手架,它允許在步驟中構建瞬態的可變表示,然後在最後的.Build()步驟中獲得最終的不變對象。