2016-01-06 33 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語句之後,這樣你就不會做兩次查找那就是我的壞 –