在 C# 中创建只读数组的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2133616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:45:52  来源:igfitidea点击:

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

c#arraysreadonly

提问by Vilx-

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?

我想从我的财产中返回一个只读数组,这是一种极不可能和原始的情况。到目前为止,我只知道一种方法 - 通过System.Collections.ObjectModel.ReadOnlyCollection<T>. 但这对我来说似乎有些尴尬,更不用说这个类失去了通过索引访问数组元素的能力补充说:哎呀,我错过了索引器)。没有更好的办法吗?可以使数组本身不可变的东西?

采纳答案by Jeff Yates

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

使用ReadOnlyCollection<T>. 它是只读的,并且与您所相信的相反,它有一个索引器。

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

数组不是一成不变的,如果不使用像ReadOnlyCollection<T>.

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

请注意,创建ReadOnlyCollection<T>包装器是一个 O(1) 操作,并且不会产生任何性能成本。

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.

更新
其他答案建议只将集合转换为 newer IReadOnlyList<T>,它扩展IReadOnlyCollection<T>到添加索引器。不幸的是,这实际上并不能让您控制集合的可变性,因为它可以转换回原始集合类型并进行变异。

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

相反,您仍然应该使用ReadOnlyCollection<T>List<T>方法AsReadOnly(),或Arrays 静态方法AsReadOnly()有助于相应地包装列表和数组)来创建对集合的不可变访问,然后直接或作为它支持的任何一个接口公开它,包括IReadOnlyList<T>.

回答by epitka

IEnumerable comes to mind.

IEnumerable 浮现在脑海中。

回答by Morfildur

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

您可能想要实现 IEnumerable 接口并重载 this[int] 运算符以拒绝访问它的 setter

回答by BFree

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 REALLYwant an array.....

如果你真的想要返回一个数组,又怕数组的消费者弄乱内部数据,就返回一个数组的副本即可。我个人仍然认为这ReadOnlyCollection<T>是要走的路,但如果你真的想要一个数组......

回答by N8allan

From .NET Framework 2.0 and up there is Array.AsReadOnlywhich automatically creates a ReadOnlyCollectionwrapper for you.

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

回答by Warty

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

.NET Framework 4.5 引入IReadOnlyList<T>,它从IReadOnlyCollection<T>添加T this[int index] { /*..*/ get; }.

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

您可以从T[]到投射IReadOnlyList<T>。这样做的一个优点是可以(IReadOnlyList<T>)array理解地等于array; 不涉及拳击。

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

当然,由于没有使用包装器,(T[])GetReadOnlyList()因此是可变的。

回答by Henry

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

现在支持不可变集合。请参阅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)
  • .NET 4.5(或更高版本)
  • .NETStandard 1.0(或更高版本)
  • 视窗 8.0
  • 视窗电话 8.0
  • 视窗手机应用程序 8.1
  • 可移植类库(.NETFramework 4.5、Windows 8.0、WindowsPhone 8.0、WindowsPhoneApp 8.1)

回答by Matthew Steeples

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

我认识到这是一个老问题,但现在有包含ImmutableArray类型的.NET 包。内置于 .NET Core 3,可通过NuGetfor Full framework 4.5 使用