IEnumerable<T, int>, Arity and Generic Type Definitions

╄→尐↘猪︶ㄣ 提交于 2019-12-23 15:31:57

问题


I have a class Counter that counts things by key. Simplified:

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

It does a number of other things specialized to my needs, but that's the essence. So far, it works great.

Now I want to enable it to be used in a Linq query (with both the keys and the values). Do to that, I think I need to implement

IEnumerable<T, int>

So I added:

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

Which unfortunately leads to the compiler error

The number of generic arguments provided doesn't equal the arity of the generic type definition. Parameter name: instantiation

Questions

  1. What the heck is arity?
  2. Am I on the right path to make this type usable from Linq?
  3. How do I fix the implementation?

UPDATE: Typo

I had a typo while simplifying my code to post. The code is in fact attempting to implement IEnumerable<KeyValuePair<T, int>> and not IEnumerable<T, int>


回答1:


  1. Arity is a fancy way of saying "the number of parameters". That's the root of words "binary" (taking two parameters), "unary" (taking one parameter), and "ternary" (taking three parameters).
  2. No, not quite: LINQ is rooted in functional programming, and functional programming hates all state, preferring functions with no side effects. Unfortunately, your counter keeps state: that's the counts dictionary that you modify, which is a side effect.
  3. If you want to count things by key, LINQ already offers you adequate facilities to do so.

Here is how you can get item counts by key:

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


来源:https://stackoverflow.com/questions/16270722/ienumerablet-int-arity-and-generic-type-definitions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!