NOt*_*Dev 5 c# generics extension-methods covariance generic-variance
我正在尝试编写一个扩展方法,该方法将转换IDictionary<K, S<V>>保存任何类型的collection/sequence(S<V>),ILookup<K, V>在这些情况下,这是更合适的数据结构.这意味着我希望我的扩展能够在不同的S类型和接口上工作:
IDictionary<K, IEnumerable<V>>IDictionary<K, ICollection<V>>IDictionary<K, List<V>>理想情况下,我不想为每种可能的集合类型编写单独的实现,并且我希望类型推断能够完成它的工作.
我试过的是:
public static ILookup<TKey, TValue>ToLookup<TKey, TCollection, TValue>(
this IDictionary<TKey, TCollection> dictionary)
where TCollection : IEnumerable<TValue>
Run Code Online (Sandbox Code Playgroud)
但它没有TValue参数列表,所以类型推断无法弄明白 - 我得到"方法ToLookup的类型参数不能从用法推断".
是否有可能以某种方式以某种方式工作,而不是在方法中添加假的TValue参数?
预期用途的示例
我希望所有上述调用都成为可能,并导致调用我的单个扩展方法:
var dictOfIEnumerables = new Dictionary<int, IEnumerable<int>>();
var lookupFromIEnumerables = dictOfIEnumerables.ToLookup();
var dictOfICollections = new Dictionary<int, ICollection<int>>();
var lookupFromICollections = dictOfICollections.ToLookup();
var dictOfLists = new Dictionary<int, List<int>>();
var lookupFromLists = dictOfLists.ToLookup();
Run Code Online (Sandbox Code Playgroud)
因为所有集合都实现了IEnumerable<T>,所以我们可以使用它来代替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);
}
Run Code Online (Sandbox Code Playgroud)
似乎没有办法使类型推断起作用,但是如果您强制转换字典,则此方法将起作用:
((IDictionary<int, IEnumerable<int>>)dictOfLists).ToLookup()
Run Code Online (Sandbox Code Playgroud)
您还可以将列表添加到 IEnumerables 字典中,并在需要时将它们转换回来。
| 归档时间: |
|
| 查看次数: |
326 次 |
| 最近记录: |