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

发布于 2024-08-19 06:35:41 字数 220 浏览 11 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

女中豪杰 2024-08-26 06:35:42

使用 ReadOnlyCollection。它是只读的,并且与您的想法相反,它有一个索引器。

数组不是不可变的,如果不使用像 ReadOnlyCollection 这样的包装器,就无法使它们成为不可变的。

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

更新
其他答案建议将集合转换为较新的 IReadOnlyList,它扩展了 IReadOnlyCollection 以添加索引器。不幸的是,这实际上并不能让您控制集合的可变性,因为它可以被强制转换回原始集合类型并发生变化。

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

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

生来就爱笑 2024-08-26 06:35:42

.NET Framework 4.5 引入了 IReadOnlyList,它从 IReadOnlyCollection 扩展而来,添加了 T this[int index] { /*..*/ get; }

您可以从 T[] 转换为 IReadOnlyList。这样做的一个优点是 (IReadOnlyList)array 可以理解为等于 array;不涉及拳击。

当然,由于未使用包装器,(T[])GetReadOnlyList() 将是可变的。

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

输什么也不输骨气 2024-08-26 06:35:42

从 .NET Framework 2.0 及更高版本开始,Array.AsReadOnly 会自动创建为您提供的 ReadOnlyCollection 包装器。

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

[浮城] 2024-08-26 06:35:42

我认识到这是一个老问题,但现在有一些 .NET 包包含 ImmutableArray 类型。内置于 .NET Core 3,并可通过 NuGet 获取完整框架 4.5 及以上版本

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

红尘作伴 2024-08-26 06:35:42

如果你确实想要返回一个数组,但又担心数组的使用者会弄乱内部数据,那么只需返回数组的副本即可。就我个人而言,我仍然认为 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.....

生生不灭 2024-08-26 06:35:42

现在支持不可变集合。
请参阅 https://www.nuget.org/packages/System.Collections.Immutable

支持以下任意版本:

  • .NET 4.5(或更高版本)
  • .NETStandard 1.0(或更高版本)
  • Windows 8.0
  • WindowsPhone 8.0
  • WindowsPhoneApp 8.1
  • 可移植类库(.NETFramework 4.5、Windows 8.0、WindowsPhone 8.0、WindowsPhoneApp 8.1)

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)
对你的占有欲 2024-08-26 06:35:42

我想到了 IEnumerable。

IEnumerable comes to mind.

尽揽少女心 2024-08-26 06:35:42

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文