2013-04-29 65 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