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

3

在将不同的实现了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<int>/Stack<int>/...无法隐式转换为IReadOnlyCollection<int>。存在显式转换。你是否漏掉了一个强制转换?
(这不是实际文本,但我相信您不希望我在此处复制粘贴德语文本。)
如果我执行强制转换,则会将

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

甚至可以通过

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

一切都很好,没有编译或运行时错误。


List是一个通用类;但例如LinkedListList类的子类。这可能涉及到继承问题,但我也想了解答案。 - stuck
我也无法重现这个问题 - 也许你能告诉我们编译器具体报了什么错误或警告,这可能是一个线索。 - Damien_The_Unbeliever
@J.Steen,除了使用.NET版本之外,您有没有想过其他选项可能会影响编译器的行为? - Kjara
我没有安装Resharper,所以我猜测问题可能出在编译器上。 - Kjara
2
看这里:https://dev59.com/cVwY5IYBdhLWcg3wU2XA#32762752 - JPhil
显示剩余7条评论
1个回答

2
如果您的目标是.NET 4.6或更高版本,则可以编译此代码。例如,SortedSet 实现了 IReadOnlyCollection 接口(可通过右键单击并选择“转到定义”进行检查)。完整的列表如下:ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable, ICollection, ISerializable, IDeserializationCallback, IReadOnlyCollection<T>。而在4.5版本中,它只实现了以下接口:ISet<T>, ICollection<T>, IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback。如果文档说明不同,则很抱歉,文档是错误的。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接