将项目添加到 ImmutableDictionary<TKey, TValue> 内的 ImmutableList<T>
Adding items to an ImmutableList<T> inside an ImmutableDictionary<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。如何在不重建整个词典的情况下替换词典中的列表?
答案就在我眼皮底下。就像我在添加项时需要调用Add并覆盖原来的变量一样,我需要在Dictionary上调用SetItem。有道理!
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();
最后但同样重要的是,我们在这里使用了一个转换器。
您可以使用 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));
我似乎无法弄清楚如何将项目添加到 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。如何在不重建整个词典的情况下替换词典中的列表?
答案就在我眼皮底下。就像我在添加项时需要调用Add并覆盖原来的变量一样,我需要在Dictionary上调用SetItem。有道理!
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();
最后但同样重要的是,我们在这里使用了一个转换器。
您可以使用 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));