2016-01-06 68 views
0

我想在Dictionary上创建一个通用的聚合扩展。事情是这样的..字典C的聚合扩展#

void Main(){ 
    var foo = new Dictionary<string, Metric>(); 
    foo["first"] = new Metric(5); 
    foo["sec"] = new Metric(10); 

    foo.Aggregate<string, Metric, int>("first", new Metric(5)); 
} 

public class Metric : IAggregatable<int> { 
    public int Total { get; set; } 

    public Metric(int total) { 
     Total = total; 
    } 

    public void Aggregate(int value) { 
     Total += value; 
    } 
} 

public static class DictionaryExtensions { 
    public static void Aggregate<TKey, TValue, T>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TValue : IAggregatable<T> { 
     TValue result; 
     if (dic.TryGetValue(key, out result)) 
      dic[key].Aggregate(value.Total); 
     else 
      dic[key] = value; 
    } 
} 

public interface IAggregatable<T> { 
    T Total { get; set; } 
    void Aggregate(T value); 
} 

这种运作良好,但我必须每次我打这个电话给Aggregate(...)时指定的泛型类型参数。这可以在main()中看作foo.Aggregate<string, Metric, int>("first", new Metric(5));。有没有更清晰的方法来获得这个功能,因为我宁愿不必每次都指定泛型类型参数。

回答

4

我觉得你的界面有点笨重。你不需要知道你的指标的内部。要进行汇总,您只需要知道什么可以汇总,而不是如何汇总。该如何可以通过执行来处理:

using System.Collections.Generic; 

namespace ConsoleApplication3 
{ 
    public class Metric : IAggregatable<Metric> 
    { 
     public int Total { get; set; } 

     public Metric(int total) 
     { 
      Total = total; 
     } 

     public void Aggregate(Metric other) 
     { 
      Total += other.Total; 
     } 
    } 

    public static class DictionaryExtensions 
    { 
     public static void Aggregate<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TValue : IAggregatable<TValue> 
     { 
      TValue result; 
      if (dic.TryGetValue(key, out result)) 
       dic[key].Aggregate(value); 
      else 
       dic[key] = value; 
     } 
    } 

    public interface IAggregatable<T> 
    { 
     void Aggregate(T other); 
    } 

    class Program 
    { 
     void Main() 
     { 
      var foo = new Dictionary<string, Metric>(); 
      foo["first"] = new Metric(5); 
      foo["sec"] = new Metric(10); 

      foo.Aggregate("first", new Metric(5)); 
     }   
    } 
} 
+1

为什么要用'TryGetValue'如果你不打算使用'result'? – juharr

+0

它应该是'result.Aggregate(value)'在if语句之后,这样你就不会做两次查找那就是我的坏 –