好的,我理解不可变类型本质上是线程安全的,或者说我在各种地方都读到过这样的说法,也认为我理解了为什么会这样。如果实例的内部状态在对象创建后无法被修改,那么似乎并没有使用该实例本身的并发访问问题。
因此,我可以创建以下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视为可变的?
ImmutableList: IEnumerable where T: struct 这个类是否应该是唯一真正被认为是不可变的类型?
感谢任何关于此问题的输入。
更新:很多答案/评论都集中在我发布的ImmutableList的特定实现上,这可能不是一个非常好的例子。但问题不在于实现。我要问的问题是,考虑到不可变类型所涉及的一切,ImmutableList是否真的是一个不可变类型。
Remove
和Add
方法中存在无限递归;-) - BrokenGlassT
集合指始终包含相同实例的集合。如果我有一个包含五个Car
实例的ImmutableList<Car>
,只要它存在,它始终会保存这五个Car
实例。尽管有人可能会给车涂上漆或偷走轮罩,但它们仍然是同样的五辆车。 - supercat