Подтвердить что ты не робот

Каков наилучший способ создания массива readonly в С#?

У меня очень маловероятная и оригинальная ситуация, когда я хочу вернуть массив readonly из моего свойства. Пока я знаю только один способ сделать это - через System.Collections.ObjectModel.ReadOnlyCollection<T>. Но мне это кажется неудобным, не говоря уже о том, что этот класс теряет возможность доступа к элементам массива по индексу (добавил: whoops, я пропустил индексатор). Нет ли лучшего способа? Что-то, что может сделать массив неизменным?

4b9b3361

Ответ 1

Используйте ReadOnlyCollection<T>. Он доступен только для чтения и, вопреки тому, что вы считаете, имеет указатель.

Массивы не являются неизменяемыми, и их невозможно сделать без использования обертки, например ReadOnlyCollection<T>.

Обратите внимание, что создание обертки ReadOnlyCollection<T> является операцией O (1) и не несет каких-либо затрат на производительность.

Обновление
Другие ответы предложили просто набросать коллекции на новый IReadOnlyList<T>, который расширяет IReadOnlyCollection<T> для добавления индексатора. К сожалению, это фактически не дает вам контроля над изменчивостью коллекции, поскольку она может быть отброшена в исходный тип коллекции и изменена.

Вместо этого вы все равно должны использовать метод ReadOnlyCollection<T> (List<T> AsReadOnly() или Array статический метод AsReadOnly() помогает связать списки и массивы соответственно), чтобы создать неизменный доступ к коллекции, а затем разоблачить это либо напрямую, либо как любой из интерфейсов он поддерживает, включая IReadOnlyList<T>.

Ответ 2

В .NET Framework 4.5 представлен IReadOnlyList<T>, который простирается от IReadOnlyCollection<T>, добавляя T this[int index] { /*..*/ get; }.

Вы можете использовать от T[] до IReadOnlyList<T>. Одним из преимуществ этого является то, что (IReadOnlyList<T>)array понятно равно array; бокс не участвует.

Конечно, поскольку оболочка не используется, (T[])GetReadOnlyList() будет изменяться.

Ответ 3

Если вы действительно хотите вернуть массив, но опасаетесь, что потребитель массива будет работать с внутренними данными, просто верните копию массива. Лично я все еще думаю, что ReadOnlyCollection<T> - это путь, но если вы ДЕЙСТВИТЕЛЬНО хотите массив.....

Ответ 5

IEnumerable приходит на ум.

Ответ 6

Возможно, вы захотите реализовать интерфейс IEnumerable и перегрузить этот оператор [int], чтобы запретить доступ к нему setter