Ala*_*ain 4 c# extension-methods dictionary .net-4.0
我正在寻找一种扩展方法或任何其他建议,可以帮助我尽可能简洁地使用此代码.
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);
Run Code Online (Sandbox Code Playgroud)
上面的代码有一个相当明确的目的,我用一个复合键将值分成组.但是,此代码将失败,因为字典最初为空,而+ =运算符将不知道在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;
}
Run Code Online (Sandbox Code Playgroud)
但是,当然,即使这样也无法编译,因为没有办法限制V的类型,使得运算符+=
存在.
规则
作为参考 - 在类的其他地方,键被定义为一个实际的元组(只有命名参数),这就是为什么它可以用作字典键:
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; } }
}
Run Code Online (Sandbox Code Playgroud)
解
感谢Jon Skeet将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;
}
Run Code Online (Sandbox Code Playgroud)
例子:
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));
Run Code Online (Sandbox Code Playgroud)
无尽的乐趣!
首先,我建议不要做任何可能的事情,尽可能缩短可读性的潜在成本.例如,我会在foreach
主体周围添加大括号,如果更可读的解决方案最终是两行而不是一行,我会对此感到高兴.
其次,我将假设对于您感兴趣的任何类型,默认值是自然零.
现在,你可以写:
public static void AddOrSet<K, V>(this Dictionary<K, V> dict,
K key, V value, Func<V, V, V> addition)
{
V existing;
dict.TryGetValue(key, out existing);
dict[key] = addition(existing, value);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用:
EventGroupLayerLosses.AddOrSet(new EventGroupIDLayerTuple(evt.EventGroupID, lyr),
GetEL(evt.AsIfs, lyr.LimitInMillions, lyr.AttachmentInMillions),
(x, y) => x + y);
Run Code Online (Sandbox Code Playgroud)
使用ConcurrentDictionary
也会很好用.
另外,如果可以,我会尝试将其作为LINQ查询重新编写.如果混合使用GroupBy
,我会不会感到惊讶,Sum
并ToDictionary
允许你以声明的方式表达整个事物.
归档时间: |
|
查看次数: |
1900 次 |
最近记录: |