我有
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”]尚不存在的情况下,使Dictionary返回一个新列表,但我找不到任何东西。
这是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>
接口。但是至少,如果您经常使用上面发布的上述模式,则可以考虑将字典的直接用法与某些封装互换,这可以使您琐碎的任务并消除代码重复。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句