Pat*_*eam 6 .net c# dictionary base-class-library
我知道Dictionary<K,V>.TryAdd().NET Core 2.0 中添加的方法通过在添加元素之前仅检查一次字典是否包含键来提高性能,这与以下方法不同:
if(!dico.ContainsKey(key)) { dico.Add(key,val); } // .Add() calls ContainsKey() a second time
Run Code Online (Sandbox Code Playgroud)
但是出于性能原因,我只想val在以下情况下才进行延迟构建!dico.ContainsKey(key):
if(!dico.ContainsKey(key)) { dico.Add(key, new Value()); }
Run Code Online (Sandbox Code Playgroud)
在这种情况下TryAdd(),由于该值不是延迟构建的,因此会降低性能。
dico.TryAdd(key,new Value());
Run Code Online (Sandbox Code Playgroud)
有没有办法既进行一次ContainsKey()调用又延迟构建值?就像是AddWithNoContainsKeyCheck():
if(!dico.ContainsKey(key)) { dico.AddWithNoContainsKeyCheck(key, new Value()); }
Run Code Online (Sandbox Code Playgroud)
CollectionsMarshal.GetValueRefOrAddDefault是的,通过使用.NET 6 及更高版本中提供的高级 API 是可能的:
/// <summary>
/// Uses the specified function to add a key/value pair to the dictionary,
/// if the key does not already exist.
/// </summary>
public static bool TryAdd<TKey, TValue>(
this Dictionary<TKey, TValue> dictionary,
TKey key,
Func<TKey, TValue> valueFactory,
out TValue value) where TKey : notnull
{
ArgumentNullException.ThrowIfNull(dictionary);
ArgumentNullException.ThrowIfNull(valueFactory);
ref TValue valueRef = ref CollectionsMarshal
.GetValueRefOrAddDefault(dictionary, key, out bool exists);
if (!exists)
{
try { valueRef = valueFactory(key); }
catch { dictionary.Remove(key); throw; }
value = valueRef;
return true;
}
value = valueRef; // It was `value = default` in the original answer
return false;
}
Run Code Online (Sandbox Code Playgroud)
返回对存储在字典中的值的引用CollectionsMarshal.GetValueRefOrAddDefault。如果失败,删除新添加的密钥很重要。否则,带有 a 的键将会无意中添加到字典中。valueFactorydefault(TValue)
注意:这个答案中的扩展方法TryAdd提供了相同的功能,但更方便、更流畅GetOrAdd。在实践中很少需要返回bool值(如果该值已创建或已存在则传达信息)。
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |