4

我有一个类Counter可以按键计数。简化:

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. 什么是arity?
  2. 我是否在正确的道路上使这种类型可以从 Linq 中使用?
  3. 如何修复实施?

更新:错字

在简化要发布的代码时,我有一个错字。该代码实际上是在尝试实现IEnumerable<KeyValuePair<T, int>>而不是IEnumerable<T, int>

4

1 回答 1

9
  1. Arity 是说“参数数量”的一种奇特方式。这就是单词“binary”(带两个参数)、“unary”(带一个参数)和“ternary”(带三个参数)的词根。
  2. 不,不完全是:LINQ 植根于函数式编程,而函数式编程讨厌所有状态,更喜欢没有副作用的函数。不幸的是,您的计数器保持状态:那counts是您修改的字典,这是一个副作用。
  3. 如果您想按键计数,LINQ 已经为您提供了足够的工具来执行此操作。

以下是如何通过键获取项目计数:

var counters = keyedData
    .GroupBy(item => item.MyKey)
    .ToDictionary(g => g.Key, g => g.Count());
于 2013-04-29T03:27:01.413 回答