2013-04-29 45 views
3

我有一個類計數器按鍵計數的東西。簡化:IEnumerable <T, int>,Arity和泛型類型定義

public class Counter<T> { 
    private Dictionary<T, int> counts; 

    public void Increment(T key) { 
     int current; 
     bool exists = counts.TryGetValue(key, out current); 
     if (exists) { 
      counts[key]++; 
     } else { 
      counts[key] = 1; 
     } 
    } 
} 

它做了一些專門的,以我的需要其他的東西,但是這是本質。到目前爲止,它工作得很好。

現在我想讓它在Linq查詢中使用(同時使用鍵和值)。做到這一點,我想我需要實現

IEnumerable<T, int> 

於是我說:

public class Counter<T> : IEnumerable<KeyValuePair<T, int>> { 
    // ... 
    IEnumerator<KeyValuePair<T, int>> 
    IEnumerable<KeyValuePair<T, int>>.GetEnumerator() 
    { 
     return ((IEnumerable<KeyValuePair<T, int>>)counts).GetEnumerator(); 
    } 
    System.Collections.IEnumerator 
    System.Collections.IEnumerable.GetEnumerator() 
    { 
     return counts.GetEnumerator(); 
    } 

不幸導致編譯器錯誤

提供的通用參數數量不等同於泛型類型定義的參數。 參數名:實例

問題

  1. 到底什麼是元數?
  2. 我在正確的道路上使這種類型可用Linq?
  3. 如何解決實施問題?

UPDATE:錯字

我有一個錯字,同時簡化了我的代碼發佈。該代碼實際上是在試圖實施IEnumerable<KeyValuePair<T, int>>而不是IEnumerable<T, int>

+0

在#1。 IEnumerable 。 *一* *這是* arity。*您正試圖提供。 – 2013-04-29 03:20:51

+0

@AnthonyPegram:只有一個*泛型類型參數*。其他類型* int *是固定的。這是不允許的?你能幫我一個參考嗎? – 2013-04-29 03:23:21

+3

** Downvoter **:我希望知道你在這個問題上找不到什麼。 – 2013-04-29 03:24:09

回答

7
  1. 元數是在說「參數的個數」的一個奇特的方式。這是「二進制」(取兩個參數),「一元」(取一個參數)和「三元」(取三個參數)的詞根。
  2. 不,不完全是這樣的:LINQ植根於函數式編程,函數式編程不喜歡所有狀態,更喜歡沒有副作用的函數。不幸的是,你的計數器保持狀態:這是你修改的counts字典,這是一個副作用。
  3. 如果您想按鍵計算東西,LINQ已經爲您提供了足夠的設施來完成這項工作。

這裏是你如何可以得到關鍵的項目計數:

var counters = keyedData 
    .GroupBy(item => item.MyKey) 
    .ToDictionary(g => g.Key, g => g.Count()); 
+0

謝謝。我不明白幾點。 #2:我可以在'字典'上使用Linq,它保持與我的'計數器'一樣的狀態。我的類型只是提供了一個方便的包裝。我的類型有什麼不同? #3:'計數器'每個具體鍵只有一個條目。 Count()如何處理它? – 2013-04-29 03:32:41

+0

@EricJ。 '字典'作爲LINQ語句的輸出*生成*。該字典是「製造」,然後給你。如果再次調用'ToDictionary',則會生成一個新實例。另一方面,'counter'在遍歷輸入的過程中被修改。如果你選擇迭代兩次,計數器會增加兩次。如果您選擇停止在序列中間進行迭代,則不會計算部分元素。 – dasblinkenlight 2013-04-29 03:40:02

+0

@EricJ。在#3上,'keyedData'是你提供給你的'Counter ',而不是'counter'。它做同樣的事情:按組分,並計數每組中的項目數量。基本上,這就是你的'計數器'在沒有明確字典的情況下重新實現(當然,它在LINQ的實現中存在,但你無法訪問它,並且它是ToDictionary方法的本地實現,所以它以完整的形式返回給你,即一切都計算在內)。 – dasblinkenlight 2013-04-29 03:41:41