简体   繁体   中英

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

I've got the extremely unlikely and original situation of wanting to return a readonly array from my property. So far I'm only aware of one way of doing it - through the System.Collections.ObjectModel.ReadOnlyCollection<T> . But that seems somehow awkward to me, not to mention that this class loses the ability to access array elements by their index ( added: whoops, I missed the indexer ). Is there no better way? Something that could make the array itself immutable?

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 Array s 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; } 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.

从 .NET Framework 2.0 开始, Array.AsReadOnly会自动为您创建一个ReadOnlyCollection包装器。

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.....

I recognise that this is an old question, but there are packages for .NET now that contain an ImmutableArray type. Built in to .NET Core 3, and available via NuGet for Full framework 4.5 onwards

IEnumerable 浮现在脑海中。

您可能想要实现 IEnumerable 接口并重载 this[int] 运算符以拒绝访问它的 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM