将项目添加到不<T>可变词典中的不可变列表<TKey,TValue>



我似乎不明白如何将项目添加到ImmutableDictionary中的ImmutableList

我有以下变量:

ImmutableDictionary<string, ImmutableList<string>> _attributes = ImmutableDictionary<string, ImmutableList<string>>.Empty;

我试图在列表中添加一个值:

string[] attribute = line.Split(':');
if (!_attributes.ContainsKey(attribute[0]))
_attributes = _attributes.Add(attribute[0], ImmutableList<string>.Empty);
if (attribute.Length == 2)
_attributes[attribute[0]] = _attributes[attribute[0]].Add(attribute[1]);

然而,我得到一个错误,说ImmutableList没有setter。如何替换字典中的列表而无需重新构建整个字典?

ImmutableCollections提供了一系列不同的方法来构造它们。
一般的指导是首先填充它们,然后使它们不可变。

Create+AddRange

ImmutableDictionary<string, string> collection1 = ImmutableDictionary
.Create<string, string>(StringComparer.InvariantCultureIgnoreCase)
.AddRange(
new[]
{
new KeyValuePair<string, string>("a", "a"),
new KeyValuePair<string, string>("b", "b"),
});

我们创建了一个空集合,然后又创建了一个包含一些值的集合。

Create+Builder

ImmutableDictionary<string, string>.Builder builder2 = ImmutableDictionary
.Create<string, string>(StringComparer.InvariantCultureIgnoreCase)
.ToBuilder();
builder2.AddRange(
new[]
{
new KeyValuePair<string, string>("a", "a"),
new KeyValuePair<string, string>("b", "b"),
});
ImmutableDictionary<string, string> collection2 = builder2.ToImmutable();

创建了一个空集合,然后将其转换为构造器。
我们已经用值填充了它。
最后构造了不可变集合。

CreateBuilder

ImmutableDictionary<string, string>.Builder builder3 = ImmutableDictionary
.CreateBuilder<string, string>(StringComparer.InvariantCultureIgnoreCase);
builder3
.AddRange(
new[]
{
new KeyValuePair<string, string>("a", "a"),
new KeyValuePair<string, string>("b", "b"),
});
ImmutableDictionary<string, string> collection3 = builder3.ToImmutable();

这是前一种情况(Create+ToBuilder)的缩写形式

CreateRange

ImmutableDictionary<string, string> collection4 = ImmutableDictionary
.CreateRange(new[]
{
new KeyValuePair<string, string>("a", "a"),
new KeyValuePair<string, string>("b", "b"),
});

这是第一种情况(Create+AddRange)的简写形式

ToImmutableDictionary

ImmutableDictionary<string, string> collection5 = new Dictionary<string, string>
{
{ "a", "a" },
{ "b", "b" }
}.ToImmutableDictionary();

最后但并非最不重要的是,这里我们使用了转换器。

答案就在我眼皮底下。就像在添加项时需要调用Add并覆盖原始变量一样,我需要在Dictionary上调用SetItem。是有意义的!

您可以使用ImmutableDictionary.TryGetValue方法,以便将字典查找从3次减少到2次。

var _attributes = ImmutableDictionary.Create<string, ImmutableList<string>>();
string[] parts = line.Split(':');
if (parts.Length == 2)
{
string attributeName = parts[0];
string attributeValue = parts[1];
if (_attributes.TryGetValue(attributeName, out var list))
{
_attributes = _attributes.SetItem(attributeName, list.Add(attributeValue));
}
else
{
_attributes = _attributes.Add(attributeName, ImmutableList.Create(attributeValue));
}
}

如果您希望将线程安全作为原子操作来更新字典,您可以使用ImmutableInterlocked.AddOrUpdate方法:

ImmutableInterlocked.AddOrUpdate(ref _attributes, attributeName,
_ => ImmutableList.Create(attributeValue),
(_, existing) => existing.Add(attributeValue));

相关内容

  • 没有找到相关文章

最新更新