2011-08-28 167 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>(假设您可以相信消费者不会投出结果)。