我使用的是ImmutableList,如下所示:
使用Nuget引用该包,以下是使用代码:
using System.Collections.Immutable;
private ImmutableList<Data> immutableList = ImmutableList.Create<Data>();
// Write Action
Action writeAction = (() =>
{
Data writeData = new Data();
// Fill Data type with valid values
immutableList.Add(writeData);
});
上面的代码不会将任何数据添加到Immutable列表中。它仍然是空的,我无法弄清楚所有数据是否有效的原因。类似的代码用于填充其他数据结构,如ConcurrentQueue和ConcurrentBag,它工作正常。
我在使用不可变列表时遗漏了什么,是否需要更正? 请注意这是一个多线程操作,但这不是问题,因为这个数据结构是线程安全的。
答案 0 :(得分:12)
由于名称建议列表是不可变的,即您无法将该项目添加到原始列表中。在MSDN链接的备注部分:
当您从不可变列表副本中添加或删除项目时 原始列表是使用添加或删除的项目,以及 原始列表不变。
同样来自here,添加方法文档:
它返回一个添加了对象的新的不可变列表,如果是,则返回当前列表 已包含指定的对象。
添加将获得添加了项目的新列表引用(原始列表将保持不变):
immutableList = immutableList.Add(writeData);
答案 1 :(得分:2)
不可变列表是不会更改的列表。以下是MSDN对其含义的描述:
当您从不可变列表中添加或删除项目时,将使用添加或删除的项目创建原始列表的副本,并且原始列表不会更改。
这意味着每次执行Add这样的操作时,原始列表都不会更改,但会返回带有添加元素的新列表。这意味着您需要使用这样的代码来获得正确的列表:
immutableList = immutableList.Add(writeData);
这让我觉得你在错误的情况下使用它。
答案 2 :(得分:0)
=
这对我来说很有效。
答案 3 :(得分:-1)
答案已经说明不可变列表确实是不可变的,例如,当您添加项目时,您必须将添加操作中的新不可变列表指定给相同的变量。
更容易使用的一种可能性是使用功能容器类包装不可变列表,如下面的代码,可以将其粘贴到 Linqpad 5 中(确保按 F4 将 Nuget 引用添加到 System.Collections.Immutable 并选择来自该程序集的命名空间)。
void Main()
{
var numbersInImmutableList = new ImmutableWrappedList<int>();
numbersInImmutableList.AddRange(new[] { 3, 1, 4, 1, 5, 9, 2 });
numbersInImmutableList.AddRange(new[]{ 2, 7, 1, 8, 2, 1, 8 });
numbersInImmutableList.RemoveAt(2);
numbersInImmutableList.Dump();
}
public class ImmutableWrappedList<T> {
public ImmutableList<T> _internalList {get; private set; }
public ImmutableWrappedList()
{
_internalList = ImmutableList.Create<T>();
}
public void Clear() => _internalList.Clear();
public void AddRange(IEnumerable<T> itemsToAdd) => _internalList = _internalList.AddRange(itemsToAdd);
public void Add(T itemToAdd) => _internalList = _internalList.Add(itemToAdd);
public void Remove(T itemToAdd) => _internalList = _internalList.Remove(itemToAdd);
public void RemoveAt(int index) => _internalList = _internalList.RemoveAt(index);
public void Insert(T itemToAdd, int position) => _internalList = _internalList.Insert(position, itemToAdd);
}