2011-08-28 153 views
0

是否有更好的方法確保以下Test類的不變性,而不必在每次獲得屬性Array獲得處理時都返回數組的新深度副本(請假設DeepCopy()是一種擴展方法,該方法會創建新的深度複製的數組)?公共屬性和不變性

public class Test 
{ 
    private SomeObject[] _array; 

    public SomeObject[] Array 
    { 
     get { return (_array.DeepCopy();) } 
    } 

    public Test(SomeObject[] array) 
    { 
     _array = array.DeepCopy(); 
    } 
} 

這會在初始化時創建一個深層副本,而每次訪問該屬性時都會創建一個深層副本。有沒有更好的方法來實現不變性?

回答

2

.NET 沒有「深層次不可變」的集合,它使成員元素不可變。例如。 ReadonlyCollection<T>可以防止元素被添加/刪除,但是單個元素不會被複制,因此仍然可以更改其屬性。

因此,您必須複製構成集合的元素,如果它們本身不是不可變的。如果這些元素是不可改變的,那麼圍繞這個集合(如ReadonlyCollection<T>)就會足夠。


考慮BCL。像F#運行時的擴展是另一回事。

+0

你可能是指BCL,而不是CLR ...... –

+0

@Thomas:當然可以。定影... – Richard

1

System.Collections.Generic.List <>實現了一個AsReadOnly函數,並且有一個System.Collections.ReadOnlyCollectionBase類,您可以從中繼承表示一組只讀元素的類。但是,雖然這些行爲像數組,但它們不是實際的數組。實際的數組總是允許更改元素。所以我能想到的唯一選擇就是像你一樣製作副本,或者將每個級別的對象封裝在只讀封裝中。

參見:Read-only array in .NET

0

Properties should not return arrays。這是您運行FxCop時會得到的消息之一。 Microsoft網頁建議的一種解決方案是返回ReadOnlyCollection <T>,正如@BlueMonkMN所示。您也可以使用IEnumerable <T>(假設您可以相信消費者不會投出結果)。