在.NET中是否有不可变和只读的集合类型?

huangapple go评论68阅读模式
英文:

Is there an immutable and read-only collection type in .NET?

问题

在.NET中,我们拥有可读和不可变的集合类型。例如:

  • ReadOnlyCollection<T> 是列表的只读包装器。这种类型的实例不能被客户端代码修改(因此这个类型是只读的),但如果底层列表发生更改,那么这些更改会反映在 ReadOnlyCollection<T> 实例上(因此,这个类型不是不可变的)。

  • ImmutableList<T> 是一个不可变类型(一旦你有了这种类型的实例,就没有办法通过改变对象状态来修改它),但它的公共接口不是只读接口:客户端代码可以调用方法(比如 Add 方法),其目的是创建类型的新实例,而不是修改当前实例。

有时我感到需要一个既不可变又只读的具体类型。根据我的知识,.NET基类库中没有同时具备这两个特性的现有类型。我有遗漏什么吗?

你可以通过使用接口类型来接近这一点,例如以下示例:

public IReadOnlyCollection<string> GetItems()
{
  // 返回的集合是不可变对象,客户端代码视其为只读
  return new List<string>{ "foo", "bar" }.ToImmutableList();
}
英文:

In .NET we have both read-only and immutable collection types.
For instance:

  • ReadOnlyCollection<T> is a read-only wrapper around a list. Instances of this type cannot be modified by the client code (so this type is read-only), but if the underlying list changes, then those changes are reflected on the ReadOnlyCollection<T> instance (so, this type is not immutable).

  • ImmutableList<T> is an immutable type (once you have an instance of the type, there is no way to modify it by changing the object state), but it's public interface is not a read-only interface: the client code can call methods (such as the Add method) whose purpose is creating new instances of the type, without modifying the current instance.

Sometimes I feel the need for a concrete type which is both immutable and read-only.
Based on my knowledge, there is no existing type in the .NET base class library having both of these characteristics. Am I missing anything ?

The closest you can get is by using interface types, such as in the following example:

public IReadOnlyCollection<string> GetItems()
{
  // the returned collection is an immutable object and is seen as read-only by the client code
  return new List<string>{ "foo", "bar" }.ToImmutableList();
}

答案1

得分: 4

不可变性意味着只读。

ImmutableList<T>.Add 方法不会修改对象。它只是创建一个新对象的快捷方式。这与 Enumerable.Concat 非常相似,它也适用于 ReadOnlyCollection<T>。因此,对象本身保持不可变和只读。

在这个上下文中,只读和不可变之间的区别在于其他人是否可以修改集合。ReadOnlyCollection<T> 只是一个列表的包装器,因此其他人仍然可以更改列表。ImmutableList<T> 承诺没有人可以更改列表。但在语言中,这种区别不是100%一致的。例如,readonly 关键字通常用于将结构标记为不可变。

英文:

Immutability implies read only.

The ImmutableList&lt;T&gt;.Add method does not modify the object. It is just a shortcut for creating a new object. It is very similar to something like Enumerable.Concat, something that is also available on ReadOnlyCollection&lt;T&gt;. So the object itself remains immutable and read only.

The distinction between read only and immutable in this context is if someone else can modify the collection. ReadOnlyCollection&lt;T&gt; is just a wrapper around a list, so it is still possible for someone else to change the list. ImmutableList&lt;T&gt; promises that no one can change the list. But this distinction is not 100% consistent in the language. The readonly keyword is for example used to mark structs as immutable.

答案2

得分: 1

让我们退一步,就readonly和immutable这两个术语达成一致。

  1. ReadOnlyCollection<T> 不能被修改。然而,它所引用的对象列表可以被修改(除非这些对象是不可变的)。

  2. 不可变列表不能被修改。它所引用的对象列表也不能被修改。这就是区别。

换句话说,所有的不可变集合都是只读的。你得到的正是你所要求的。

从文档中:

... 当你向不可变列表添加或移除项时,会创建一个包含已添加或移除项的原始列表的副本,而原始列表保持不变...

ImmutableList<T> 实现了 IReadOnlyCollection<T>...

来源链接:https://learn.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1?view=net-7.0

英文:

Let's take a step back and agree on what the terms readonly and immutable means.

  1. A ReadOnlyCollection&lt;T&gt; cannot be modified. However, the list of objects that it refers to can be modified (unless those objects are immutable).

  2. An immutable list cannot be modified. The list of objects that it refers to, cannot be modified either. That's the difference.

In other words, all immutable collections are readonly. You're getting exactly what you're asking for.

From docs:

> ... When you add or remove items from an immutable list, a copy of the
> original list is made with the items added or removed, and the
> original list is unchanged
...
>
> ImmutableList&lt;T&gt; Implements
> IReadOnlyCollection&lt;T&gt;...

https://learn.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1?view=net-7.0

huangapple
  • 本文由 发表于 2023年2月24日 16:37:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554275.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定