Is there a better way of ensuring immutability of the following Test
class without returnin a new deep copy of the array every time property Array
gets acessed (please assume that DeepCopy()
is an extension method which makes a new deep copy of the array)?
public class Test
{
priv开发者_开发技巧ate SomeObject[] _array;
public SomeObject[] Array
{
get { return (_array.DeepCopy();) }
}
public Test(SomeObject[] array)
{
_array = array.DeepCopy();
}
}
That envolves making a deep copy at initialization and another one everytime the property gets accessed. Is there any better way to achieve immutability?
.NET1 has no "deeply immutable" collections that make member elements immutable. Eg. ReadonlyCollection<T>
prevents elements being added/removed, but the individual elements are not copied so could still have their properties changed.
Therefore you have to copy the elements making up the collection if they are not themselves immutable. If the elements were immutable putting an shallowly immutable wrapper around the collection (like ReadonlyCollection<T>
) would be sufficient.
1 Considering the BCL. Extensions like the F# runtime are a different matter.
System.Collections.Generic.List<> implements an AsReadOnly function, and there is a System.Collections.ReadOnlyCollectionBase class from which you can inherit a class that represents a collection of read-only elements. But while those behave like arrays, they are not actual arrays. An actual array always allows changing of the elements. So the only alternatives I can think of are making a copy as you are doing, or wrapping each level of objects in a read-only wrapper.
See also: Read-only array in .NET
See Properties should not return arrays. This is one of the messages you will get if you run FxCop. One solution the Microsoft page suggests is returning ReadOnlyCollection<T> as @BlueMonkMN suggests. You can also use IEnumerable<T> (assuming you can trust consumers not to cast the results).
精彩评论