gpt4 book ai didi

c# - 不变的还是不可变的?

转载 作者:可可西里 更新时间:2023-11-01 03:13:33 25 4
gpt4 key购买 nike

好吧,据我所知,不可变 类型本质上是线程安全的,或者我在很多地方都读过,我想我明白为什么会这样。如果实例的内部状态在创建对象后无法修改,那么对实例本身的并发访问似乎没有问题。

因此,我可以创建以下 List :

class ImmutableList<T>: IEnumerable<T>
{
readonly List<T> innerList;

public ImmutableList(IEnumerable<T> collection)
{
this.innerList = new List<T>(collection);
}

public ImmutableList()
{
this.innerList = new List<T>();
}

public ImmutableList<T> Add(T item)
{
var list = new ImmutableList<T>(this.innerList);
list.innerList.Add(item);
return list;
}

public ImmutableList<T> Remove(T item)
{
var list = new ImmutableList<T>(this.innerList);
list.innerList.Remove(item);
return list;
} //and so on with relevant List methods...

public T this[int index]
{
get
{
return this.innerList[index];
}
}

public IEnumerator<T> GetEnumerator()
{
return innerList.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)this.innerList).GetEnumerator();
}
}

所以问题是:这真的不可变类型吗?真的是线程安全的吗?

显然类型本身是不可变的 但绝对不能保证 T是,因此您可能会遇到与泛型类型直接相关的并发访问和线程问题。这是否意味着 ImmutableList应该被认为是可变的

应该class ImmutableList<T>: IEnumerable<T> where T: struct是唯一真正被认为不可变的类型吗?

感谢您对此问题的任何意见。

更新:很多答案/评论都集中在 ImmutableList 的特定实现上我已经发布了这可能不是一个很好的例子。但问题的关键不是实现。我要问的问题是 ImmutableList<MutableT>考虑到不可变类型所包含的一切,它确实是一个不可变类型。

最佳答案

If the inner state of an instance can not be modified once the object is created there seems to be no problems with concurrent access to the instance itself.

一般情况下,是的。

Is this really an immutable type?

简要总结一下:您有一个围绕可变列表的写时复制包装器。向不可变列表添加新成员不会改变列表;相反,它会制作底层可变列表的副本,添加到副本,并返回副本周围的包装器。

如果您包装的底层列表对象在读取时不会改变其内部状态,那么您已经满足了“不可变”的原始定义,所以,是的。

我注意到这不是一种非常有效的方式来实现不可变列表。例如,使用不可变的平衡二叉树可能会做得更好。每次制作新列表时,您的草图在时间和内存上都是 O(n);您可以毫不费力地将其改进为 O(log n)。

Is it really thread safe?

前提是底层可变列表对多个读取器是线程安全的,是的。

您可能会感兴趣:

http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx

Obviously the type itself is immutable but there is absolutely no garantee that T is and therefore you could have concurrent access and threading issues related directly with the generic type. Would that mean that ImmutableList<T> should be considered mutable?.

这是一个哲学问题,而不是技术问题。如果你有一个不可变的人名列表,并且列表永远不会改变,但是其中一个人死了,那么这个列表是“可变的”吗?我认为不会。

如果关于列表的任何问题总是有相同的答案,则列表是不可变的。在我们的人名列表中,“列表中有多少个名字?”是关于列表的问题。 “那几个人还活着?”不是关于列表的问题,而是关于列表所指人员的问题。这个问题的答案会随着时间而改变;第一个问题的答案不是。

Should class ImmutableList<T>: IEnumerable<T> where T: struct be the only type truely considered immutable?

我没有关注你。将 T 限制为结构如何改变任何事情?好的,T 仅限于结构。我做了一个不可变的结构:

struct S
{
public int[] MutableArray { get; private set; }
...
}

现在我做了一个 ImmutableList<S> .是什么阻止我修改存储在 S 实例中的可变数组?仅仅因为列表是不可变的并且结构是不可变的并不会使数组不可变。

关于c# - 不变的还是不可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9009627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com