C# IDictionary上的单一扩展方法<;K、 IEnumerable/IList/ICollection<;V>&燃气轮机;

C# IDictionary上的单一扩展方法<;K、 IEnumerable/IList/ICollection<;V>&燃气轮机;,c#,generics,extension-methods,covariance,generic-variance,C#,Generics,Extension Methods,Covariance,Generic Variance,我正在尝试编写一个扩展方法,将保存任何类型的集合/序列(S)的IDictionary转换为ILookup,在这些情况下,这是更合适的数据结构。这意味着我希望我的扩展能够处理不同的S类型和接口: IDictionary IDictionary IDictionary 理想情况下,我不想为每个可能的集合类型编写单独的实现,我希望类型推断完成它的工作 我试过的是: public static ILookup<TKey, TValue>ToLookup<TKey, TCollect

我正在尝试编写一个扩展方法,将保存任何类型的集合/序列(
S
)的
IDictionary
转换为
ILookup
,在这些情况下,这是更合适的数据结构。这意味着我希望我的扩展能够处理不同的
S
类型和接口:

  • IDictionary
  • IDictionary
  • IDictionary
理想情况下,我不想为每个可能的集合类型编写单独的实现,我希望类型推断完成它的工作

我试过的是:

public static ILookup<TKey, TValue>ToLookup<TKey, TCollection, TValue>(
    this IDictionary<TKey, TCollection> dictionary)
        where TCollection : IEnumerable<TValue>

根据我所做的测试,以下是我的结果

如果我键入dictofineumerables.ToLookup(),我会看到4个重载方法。


但是,如果我键入dictOfIEnumerables.ToLookup,因为所有集合都实现了
IEnumerable
,我们可以使用它而不是
TCollection
类型参数。不幸的是,类型推断不知道这一点。这是我编写的代码:

public static ILookup<TKey, TValue> ToLookup<TKey, TValue>
        (this IDictionary<TKey, IEnumerable<TValue>> dict)
{
    return dict.SelectMany(p => p.Value.Select
        (v => new KeyValuePair<TKey, TValue>(p.Key, v)))
        .ToLookup(p => p.Key, p => p.Value);
}
公共静态ILookup ToLookup
(本词典)
{
返回dict.SelectMany(p=>p.Value.Select
(v=>newkeyvaluepair(p.Key,v)))
.ToLookup(p=>p.Key,p=>p.Value);
}
似乎没有办法使类型推断工作,但如果您强制转换字典,此方法将工作:

((IDictionary<int, IEnumerable<int>>)dictOfLists).ToLookup()
((词典)目录列表)。托卢库普()

此外,您还可以将列表添加到IEnumerables字典中,并在需要时将其强制转换回来。

使用它时,请尝试只为generics@Mgetz-我认为这正是NOtherDev试图避免的-要么显式指定类型,要么使用伪参数强制类型。预期用法的示例可能会把事情弄清楚。是的,正如我所提到的,我想让类型推断完成它的工作。它将向问题中添加预期的用法示例。除了向方法中添加伪
TValue
-类型的参数之外,它还有可能以其他方式工作吗?我不这么认为。类型推断在创建非扩展统计时是否会因变量泛型而失效c方法?实际上,问题不在于名称冲突,问题仍然存在于
ToLookup2
。我知道我可以显式指定参数,但这正是我试图避免的。似乎我需要为每个接口复制方法。。。
((IDictionary<int, IEnumerable<int>>)dictOfLists).ToLookup()