What's the best way of creating a readonly array in C#?

徘徊边缘 提交于 2019-12-02 17:24:54
Jeff Yates

Use ReadOnlyCollection<T>. It is read-only and, contrary to what you believe, it has an indexer.

Arrays are not immutable and there is no way of making them so without using a wrapper like ReadOnlyCollection<T>.

Note that creating a ReadOnlyCollection<T> wrapper is an O(1) operation, and does not incur any performance cost.

Update
Other answers have suggested just casting collections to the newer IReadOnlyList<T>, which extends IReadOnlyCollection<T> to add an indexer. Unfortunately, this doesn't actually give you control over the mutability of the collection since it could be cast back to the original collection type and mutated.

Instead, you should still use the ReadOnlyCollection<T> (the List<T> method AsReadOnly(), or Arrays static method AsReadOnly() helps to wrap lists and arrays accordingly) to create an immutable access to the collection and then expose that, either directly or as any one of the interfaces it supports, including IReadOnlyList<T>.

.NET Framework 4.5 introduced IReadOnlyList<T> which extends from IReadOnlyCollection<T> adding T this[int index] { /*..*/ get; }.

You can cast from T[] to IReadOnlyList<T>. One advantage of this is that (IReadOnlyList<T>)array understandably equals array; no boxing is involved.

Of course, as a wrapper is not being used, (T[])GetReadOnlyList() would be mutable.

From .NET Framework 2.0 and up there is Array.AsReadOnly which automatically creates a ReadOnlyCollection wrapper for you.

If you really want an array returned, but are afraid that the consumer of the array will mess with the internal data, just return a copy of the Array. Personally I still think ReadOnlyCollection<T> is the way to go, but if you REALLY want an array.....

IEnumerable comes to mind.

You might want to implement the IEnumerable interface and overload the this[int] operator to deny access to it's setter

There is now support for Immutable collections. See https://www.nuget.org/packages/System.Collections.Immutable

This supports any of the following:

  • .NET 4.5 (or higher)
  • .NETStandard 1.0 (or higher)
  • Windows 8.0
  • WindowsPhone 8.0
  • WindowsPhoneApp 8.1
  • Portable Class Library (.NETFramework 4.5, Windows 8.0, WindowsPhone 8.0, WindowsPhoneApp 8.1)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!