每当属性Test
被攻击时,是否有更好的方法可以确保以下Array
类的不可变性而无需返回数组的新深层副本(请假设DeepCopy()
是一个扩展方法,它创建了一个新的数组深层副本)?
public class Test
{
private SomeObject[] _array;
public SomeObject[] Array
{
get { return (_array.DeepCopy();) }
}
public Test(SomeObject[] array)
{
_array = array.DeepCopy();
}
}
在每次访问属性时,它都会在初始化时进行深层复制,而另一个则进行深入复制。有没有更好的方法来实现不变性?
答案 0 :(得分:2)
.NET 1 没有“深度不可变”的集合,使成员元素不可变。例如。 ReadonlyCollection<T>
会阻止添加/删除元素,但不会复制单个元素,因此可能仍会更改其属性。
因此,如果它们本身不可变,则必须复制构成该集合的元素。如果元素是不可变的,那么在集合周围放置一个浅不可变的包装器(如ReadonlyCollection<T>
)就足够了。
1 考虑BCL。像F#运行时这样的扩展是另一回事。
答案 1 :(得分:1)
System.Collections.Generic.List&LT;&GT;实现AsReadOnly函数,并且有一个System.Collections.ReadOnlyCollectionBase类,您可以从该类继承表示只读元素集合的类。但是,虽然那些行为像数组,但它们不是实际的数组。实际数组总是允许更改元素。因此,我能想到的唯一选择是正在制作副本,或者将每个级别的对象包装在只读包装中。
答案 2 :(得分:0)
见Properties should not return arrays。这是您运行FxCop时将收到的消息之一。 Microsoft页面建议的一个解决方案是返回ReadOnlyCollection&lt; T&gt;正如@BlueMonkMN建议的那样。您还可以使用IEnumerable&lt; T&gt; (假设您可以信任消费者不要投出结果)。