IEnumerable的< T,INT>中元数和泛型类型定义中元、定义、类型、LT

2023-09-04 13:22:43 作者:烈酒情深

我有一个类的计数器的通过按键数量的东西。简化的:

 公共类反< T> {
    私人字典< T,INT>数;

    公共无效增量(T键){
        INT电流;
        布尔存在= counts.TryGetValue(键,输出电流);
        如果(存在){
            计数[关键] ++;
        } 其他 {
            计数[关键] = 1;
        }
    }
}
 

它做了一些专门的,以我的需求其他的事情,但是这是本质。到目前为止,它的伟大工程。

现在欲使其能够在LINQ查询(同时与键和值)被使用。做到这一点,我想我需要实现

 的IEnumerable< T,INT>
 
爆发,医药研发的卖铲人

于是我说:

 公共类反< T> :IEnumerable的< KeyValuePair< T,INT>> {
    // ...
    IEnumerator的< KeyValuePair< T,INT>>
    IEnumerable的< KeyValuePair< T,INT>> .GetEnumerator()
    {
        返回((IEnumerable的< KeyValuePair< T,INT>>)计数).GetEnumerator();
    }
    System.Collections.IEnumerator
    System.Collections.IEnumerable.GetEnumerator()
    {
        返回counts.GetEnumerator();
    }
 

不幸导致编译器错误

  

的规定不等于泛型类型定义的元数通用参数的个数。   参数名:实例

问题

到底是什么元数? 我是在正确的道路上,使从LINQ的这种类型的使用吗? 如何解决执行?

更新:输入错误

我有一个错字,同时简化我的code发布。在code其实是在试图实施的IEnumerable< KeyValuePair< T,INT>> ,而不是的IEnumerable< T,INT>

解决方案 元数是说参数的个数一个奇特的方式。这是字二进制(接受两个参数)根,一元(以一个参数),和三元(取三个参数)。 不,不完全:LINQ植根于函数式编程和函数式编程恨所有的状态,preferring功能,无副作用。不幸的是,你方保持状态。这就是计数您修改词典,这是一个副作用 如果您想通过按键来算的东西,LINQ已经为您提供足够的设施来做到这一点。

下面是你如何能得到项目计数者皆:

  VAR专柜= keyedData
    .GroupBy(项目=> item.MyKey)
    .ToDictionary(克=> g.Key,克=> g.Count());
 

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

What the heck is arity? Am I on the right path to make this type usable from Linq? 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>

解决方案

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