IReadOnlyCollection 上的隐式/显式转换混淆

Posted

技术标签:

【中文标题】IReadOnlyCollection 上的隐式/显式转换混淆【英文标题】:implicit/explicit cast confusion on IReadOnlyCollection 【发布时间】:2016-12-03 23:38:50 【问题描述】:

为什么不同的集合(都实现了IReadOnlyCollection 接口)在尝试将它们转换为IReadOnlyCollection 时被编译器以不同的方式处理?

IReadOnlyCollection<int> a = new List<int>();       // everything fine
IReadOnlyCollection<int> b = new HashSet<int>();    // compiler wants me to cast
IReadOnlyCollection<int> c = new Stack<int>();      // compiler wants me to cast
IReadOnlyCollection<int> d = new Queue<int>();      // compiler wants me to cast
IReadOnlyCollection<int> e = new LinkedList<int>(); // compiler wants me to cast
IReadOnlyCollection<int> f = new SortedSet<int>();  // compiler wants me to cast

我正在使用 .NET 4.5 和 VisualStudio 2015。

上述情况的编译器错误是这样的:

类型Queue&lt;int&gt;/Stack&lt;int&gt;/...不能隐式转换为IReadOnlyCollection&lt;int&gt;。存在显式转换。你错过了演员表吗?

(这不是实际文本,但我相信您不会希望我在此处复制粘贴德语文本。)

如果我做演员

IReadOnlyCollection<int> d = new Queue<int>() as IReadOnlyCollection<int>;

甚至通过

IReadOnlyCollection<int> d = (IReadOnlyCollection<int>)new Queue<int>();

一切都很好;它没有给我任何编译或运行时错误。

【问题讨论】:

据我所知,IReadOnlyCollection 自 .NET 4.5 以来就存在。 List 是普通类;但例如 LinkedList 是 List 类的子类。可能是关于继承的问题,但我也想知道这个答案。 我也无法重现这一点 - 也许作为我们的一个线索,你能告诉我们编译器具体说什么作为错误或警告吗? @J.Steen 你知道除了 .NET 版本之外还有哪些其他选项会影响编译器的行为? 看看这个:***.com/questions/32762631/… 【参考方案1】:

如果您的目标是 .NET 4.6 或更高版本,则可以编译。

在这个版本中,SortedSet(例如)确实实现了IReadOnlyCollection(通过右键单击并选择“转到定义”进行检查)。

完整列表是:

ISet、ICollection、IEnumerable、IEnumerable、ICollection、ISerializable、IDeserializationCallback、IReadOnlyCollection

在 4.5 它只实现:

ISet、ICollection、IEnumerable、ICollection、IEnumerable、ISerializable、IDeserializationCallback

如果文档另有说明,那么(恐怕)文档是错误的。

【讨论】:

以上是关于IReadOnlyCollection 上的隐式/显式转换混淆的主要内容,如果未能解决你的问题,请参考以下文章

std::array 实现上的隐式构造函数的奇怪错误

结果类型是泛型类型上的类型投影的隐式转换

仅在一个构造函数上的类成员初始化程序中的隐式常量转换 [-Werror=overflow] 溢出

mkstemp 函数的隐式声明

如何使我的应用程序对打开 PDF 文件的隐式意图可见?

第五篇:你“ 看不见 ” 的隐式转换