c# - ILookup<TKey, TElement> 不应该在 TElement 中(声明)协变吗?

标签 c# .net linq generics covariance

定义System.Linq.ILookUp<TKey, TElement>阅读

interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable 
{
    int Count { get; }

    IEnumerable<TElement> this[TKey key] { get; }

    bool Contains(TKey key);
}

IEnumerableIGrouping<TKey, TElement> 中是协变的, IGrouping<TKey, TElement>TElement 中是协变的并且界面只暴露TElement作为返回类型,我假设 ILookupTElement 中也是协变的.的确,定义

interface IMyLookup<TKey, out TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable 
{
    int Count { get; }

    IEnumerable<TElement> this[TKey key] { get; }

    bool Contains(TKey key);
}

编译没有问题。

那么,原始定义中缺少 out 关键字的原因可能是什么?可能会在 Linq 的 future 版本中添加它吗?

最佳答案

跟踪 MSDN 文档,Covariance and Contravariance in Generics在.NET Framework 4 之前已经引入了IEnumerable<T>从 .NET Framework 2.0 到 .NET Framework 3.5。然后在.NET Framework 4.0中我们可以看到IEnumerable<out T>带有类型参数 T作为协方差。

IGrouping<TKey, TElement>ILookup<TKey, TElement>自 .NET Framework 3.5 以来就已经存在。在 .NET Framework 4.0 中,前者已更新为 IGrouping<out TKey, out TElement>但后者在没有说明原因的情况下被省略了。

TKeyContains(TKey) 的实现以来不能是协变的 |和 this[TKey]防止这种情况发生。

关于TElement这个问题还不清楚。我不相信设计师只是错过了它。也许原因在于对 future 的计划。或者他们想阻止类似下面的事情,但我不知道为什么:

string[] strings = new[] {"a", "a", "b", "b", "b", "c"};
ILookup<string, string> lookup = strings.ToLookup(s => s); // Valid.
ILookup<string, object> lookup = strings.ToLookup(s => s); // Now invalid, but would correct if TElement was covariant (out TElement).

还有其他作者,关注这个问题:

ToLookup :

One slightly odd point to note is that while IGrouping is covariant in TKey and TElement, ILookup is invariant in both of its type parameters. While TKey has to be invariant, it would be reasonable for TElement to be covariant

关于c# - ILookup<TKey, TElement> 不应该在 TElement 中(声明)协变吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14883727/

相关文章:

c# - 当我在 winforms 中创建一个全新的自定义控件时,为什么要使用部分类?

c# - .Net PropertyGrid DropDownList - 返回值不同于显示值

linq - 在C#中使用Linq进行字符串替换

c# - 使用linq交叉连接未知数量的字符串数组

c# - 如何创建我的列表集合的深拷贝

c# - "object is enumerated"在 C# 中是什么意思?

c# - 从庞大的数据库中选择 id

c# - 使用c#编写adobe插件

c# - LINQ:将 object[] 转换为 int?[]

c# - 为什么一个属性被认为是不明确的,而另一个接口(interface)是只设置的?