我有
Dictionary<string, List<int>> myDict = new Dictionary<string, List<int>>();
有时我想向 myDict 添加特定字典键的数字。
我现在正在做
if (!myDict.ContainsKey(newKey)){
myDict[newKey] = new List<int>();
}
myDict[newKey].Add(myNumber);
但这似乎很容易在某些时候忘记 ContainsKey 检查而出错。 我已经搜索了一种方法,使字典返回一个新列表,以防 myDict["entry"] 尚不存在,但我找不到任何东西。
最佳答案
这是 LazyLookup
的相对简单的实现我提到的例子。它只实现 IEnumerable
出于简洁/简单的目的来回答问题。
本质上,在访问索引时,它将确保它已经被初始化为 List<T>
的新实例。类。
public class LazyLookup<TKey, TValue> : IEnumerable<List<TValue>>
{
private readonly Dictionary<TKey, List<TValue>> CachedEntries;
private readonly Func<List<TValue>> LazyListCreator;
public LazyLookup()
: this(() => new List<TValue>())
{
}
public LazyLookup(Func<List<TValue>> lazyListCreator)
{
this.LazyListCreator = lazyListCreator;
this.CachedEntries = new Dictionary<TKey, List<TValue>>();
}
public List<TValue> this[TKey key]
{
get
{
return GetOrCreateValue(key);
}
}
private List<TValue> GetOrCreateValue(TKey key)
{
List<TValue> returnValue;
if (!CachedEntries.TryGetValue(key, out returnValue))
{
returnValue = LazyListCreator();
CachedEntries[key] = returnValue;
}
return returnValue;
}
public IEnumerator<List<TValue>> GetEnumerator()
{
return CachedEntries.Values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
一些用法:
var lazyLookup = new LazyLookup<string, int>();
lazyLookup["nocheck"].Add(9001);
//outputs 9001
Console.WriteLine(lazyLookup["nocheck"][0]);
//outputs 0 as it's a newly initialized list
Console.WriteLine(lazyLookup["someOtherLookup"].Count);
此时,您可以将其更新为线程安全的(因为 GetOrCreateValue
目前不是线程安全的),或者对其进行概括,这样它就不会假设它是 List<T>
的。但任何类型,或扩展它以实现完整的IDictionary<TKey, TValue>
界面。但至少,如果经常使用您发布的上述模式,您可以考虑将字典的直接使用替换为某种封装,这可以简化您的任务并消除代码重复。
关于c# - 将元素添加到列表字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20611500/