IEnumerable <t,int =“”>,Arity和Generic Type Definitions </t,>

时间:2013-04-29 03:18:12

标签: c# .net linq linq-to-entities

我有一个类计数器按键计算事物。简化为:

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();
    }

不幸导致编译错误

  

提供的泛型参数的数量不等于泛型类型定义的arity。   参数名称:instantiation

问题

  1. 什么是arity?
  2. 我是否正确地从Linq使用此类型?
  3. 如何修复实施?
  4. 更新:错字

    我在简化要发布的代码时遇到了错误。该代码实际上是在尝试实现IEnumerable<KeyValuePair<T, int>>而不是IEnumerable<T, int>

1 个答案:

答案 0 :(得分:7)

  1. Arity是一种说“参数数量”的奇特方式。这是单词“二进制”(取两个参数),“一元”(取一个参数)和“三元”(取三个参数)的词根。
  2. 不,不完全:LINQ植根于函数式编程,函数编程讨厌所有状态,更喜欢没有副作用的函数。不幸的是,你的计数器保持状态:这是你修改的counts字典,这是副作用。
  3. 如果您想按键计算,LINQ已经为您提供了足够的设施。
  4. 以下是按键获取项目计数的方法:

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