Общественные свойства и неизменность - PullRequest
0 голосов
/ 28 августа 2011

Есть ли лучший способ обеспечить неизменность следующего класса Test без возврата в новую глубокую копию массива каждый раз, когда свойство Array получает доступ (пожалуйста, предположим, что DeepCopy() - это метод расширения, который создаетглубокая копия массива)?

public class Test
{
    private SomeObject[] _array;

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

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

Это подразумевает создание глубокой копии при инициализации и еще одну при каждом обращении к свойству.Есть ли лучший способ достичь неизменности?

Ответы [ 3 ]

2 голосов
/ 28 августа 2011

.NET 1 не имеет «глубоко неизменяемых» коллекций, которые делают элементы-члены неизменяемыми.Например.ReadonlyCollection<T> запрещает добавление / удаление элементов, но отдельные элементы не копируются, поэтому их свойства могут быть изменены.

Поэтому вам необходимо скопировать элементы, составляющие коллекцию, если они сами не являются неизменными.Если бы элементы были неизменяемыми, было бы достаточно поместить мелко неизменяемую обертку вокруг коллекции (например, ReadonlyCollection<T>).


1 Учитывая BCL.Такие расширения, как среда выполнения F #, - это другое дело.

1 голос
/ 28 августа 2011

System.Collections.Generic.List <> реализует функцию AsReadOnly, и существует класс System.Collections.ReadOnlyCollectionBase, из которого можно наследовать класс, представляющий коллекцию элементов только для чтения. Но хотя они ведут себя как массивы, они не являются реальными массивами. Фактический массив всегда позволяет изменять элементы. Поэтому единственные альтернативы, о которых я могу подумать, - это сделать копию, как вы делаете, или обернуть каждый уровень объектов в оболочку только для чтения.

См. Также: Массив только для чтения в .NET

0 голосов
/ 28 августа 2011

См. Свойства не должны возвращать массивы . Это одно из сообщений, которые вы получите, если вы запустите FxCop . Одно из решений, которое предлагает страница Microsoft, - это возвращение ReadOnlyCollection , как предлагает @BlueMonkMN. Вы также можете использовать IEnumerable (при условии, что вы можете доверять потребителям не показывать результаты).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...