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
但是出于性能原因,我只想val在以下情况下才进行延迟构建!dico.ContainsKey(key):
if(!dico.ContainsKey(key)) { dico.Add(key, new Value()); }
在这种情况下TryAdd(),由于该值不是延迟构建的,因此会降低性能。
dico.TryAdd(key,new Value());
有没有办法既进行一次ContainsKey()调用又延迟构建值?就像是AddWithNoContainsKeyCheck():
if(!dico.ContainsKey(key)) { dico.AddWithNoContainsKeyCheck(key, new Value()); }
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;
}
返回对存储在字典中的值的引用CollectionsMarshal.GetValueRefOrAddDefault。如果失败,删除新添加的密钥很重要。否则,带有 a 的键将会无意中添加到字典中。valueFactorydefault(TValue)
注意:这个答案中的扩展方法TryAdd提供了相同的功能,但更方便、更流畅GetOrAdd。在实践中很少需要返回bool值(如果该值已创建或已存在则传达信息)。
| 归档时间: | 
 | 
| 查看次数: | 132 次 | 
| 最近记录: |