【发布时间】:2018-07-18 18:56:14
【问题描述】:
我有一个ILookup<int, Derived>,我想返回一个ILookup<int, Base>,其中Derived 实现或扩展Base。
目前我使用SelectMany(),然后ToLookup()先将ILookup<int, Derived>的键值对提取到一个平面IEnumerable中,然后新建一个ILookup<int, Base>:
class Base { }
class Derived: Base { }
class Test
{
ILookup<int, Base> CastLookup(ILookup<int, Derived> existing)
{
IEnumerable<KeyValuePair<int, Base>> flattened = existing.SelectMany(
(x) => x,
(gr, v) => new KeyValuePair<int, Base>(gr.Key, (Base)v)); // I know the explicit cast can be implicit here; it is just to demonstrate where the up casting is happening.
ILookup<int, Base> result = flattened.ToLookup(
(x) => x.Key,
(x) => x.Value);
return result;
}
}
如何在不迭代其条目然后重新打包它们的情况下转换 ILookup?
注意:一个相关的问题是Shouldn't ILookup<TKey, TElement> be (declared) covariant in TElement? bigge。 Ryszard Dżegan answers 这主要是出于历史原因:ILookup<TKey, TElement> 是在具有协方差的泛型之前开发的。
Herzmeister 向 something similar 询问 Dictionary<TKey, TValue>。 Mehrdad Afshari answers 对于可变字典,协方差是不安全的。
事实上,如果Ilookup<TKey, TElement> 在TElement 中是协变的,我就不会遇到ILookup<TKey, TElement> 铸造问题的这个实例;但事实并非如此,所以我仍在继续寻找更好的方法。
注意:我当然可以编写一个扩展方法来做到这一点,但这并不妨碍迭代和重新打包所需的计算工作。
【问题讨论】:
-
@Tomer,我应该提到这个问题,但它与我通过 bigge 链接的问题相似。我认为不是重复的;是的,如果 ILookup 是协变的,我就不会问我的问题,但我并不是要求所有 ILookup/IDictionary 都是协变的,我只是想轻松地将这个特定的转换为我知道它是安全的。