我在寻找一个扩展方法或其他任何建议,可以帮助我使这个代码尽可能简明。
foreach( Layer lyr in this.ProgramLayers )
foreach( UWBCEvent evt in this.BcEvents.IncludedEvents )
EventGroupLayerLosses[new EventGroupIDLayerTuple(evt.EventGroupID, lyr)] +=
GetEL(evt.AsIfs, lyr.LimitInMillions, lyr.AttachmentInMillions);
上面的代码有一个相当明确的目的,我在瓢泼大雨值到组,复合键。 但是,此代码将失败,因为字典最初是空的和+ =运算符不知道要开始桶送行0。
我能想出的最好的是这样的:
public V AddOrSet<K, V>(this Dictionary<K, V> dict, K key, V value)
{
if( dict.ContainsKey(key) )
dict[key] += value;
else
dict[key] = value;
}
但当然,即使这样,也不能编译,因为没有办法来限制V的类型,使得运营商+=
存在。
规则
- 只有一个迭代通过双for循环。 通过前一次初始化字典,0值不允许循环。
- 辅助方法,或扩展方法都可以使用,但我想内环成为一个衬垫。
- 像通用和可重用尽可能使我不需要创建不同类型(小数,整数等)类似的桶装一堆相同的功能。
作为参考 - 别处在类中的键定义为实际的元组(只是与命名的参数),这就是为什么它可以被用来作为字典键:
private Dictionary<EventGroupIDLayerTuple, Decimal> _EventGroupLayerLosses;
public class EventGroupIDLayerTuple : Tuple<Int32, Layer>
{
public EventGroupIDLayerTuple(Int32 EventGroupID, Layer Layer) : base(EventGroupID, Layer) { }
public Int32 EventGroupID { get { return this.Item1; } }
public Layer Layer { get { return this.Item2; } }
}
解
由于乔恩斯基特传递lambda函数作为第三个参数来我的扩展方法的想法。 没有必要甚至将其限制在+ =操作了。 这是通用足够的任何操作都可以通过设置新的值,如果值已经存在。
//Sets dictionary value using the provided value. If a value already exists,
//uses the lambda function provided to compute the new value.
public static void UpdateOrSet<K, V>(this Dictionary<K, V> dict, K key, V value, Func<V, V, V> operation)
{
V currentValue;
if( dict.TryGetValue(key, out currentValue) )
dict[key] = operation(currentValue, value);
else
dict[key] = value;
}
例子:
mySums.UpdateOrSet("Bucket1", 12, (x, y) => x + y);
myStrs.UpdateOrSet("Animals", "Dog", (x, y) => x + ", " + y);
myLists.UpdateOrSet("Animals", (List<T>) Dogs, (x, y) => x.AddRange(y));
无尽的乐趣!