Why are different collections (that all implement the IReadOnlyCollection
interface) handled differently by the compiler when trying to turn them into 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
I'm using .NET 4.5 and VisualStudio 2015.
The compiler error in the above cases is this:
Type Queue<int>
/Stack<int>
/... cannot be implicitly converted into IReadOnlyCollection<int>
. An explicit conversion exists. Are you missing a cast?
(This is not the actual text, but I believe you wouldn't want me to copy-paste a German text here.)
If I do the cast by
IReadOnlyCollection<int> d = new Queue<int>() as IReadOnlyCollection<int>;
or even by
IReadOnlyCollection<int> d = (IReadOnlyCollection<int>)new Queue<int>();
everything is fine; it gives me no compilation or run-time errors.
If you target .NET 4.6 or above this does compile.
At this version SortedSet
(for example) does implement the IReadOnlyCollection
(checked by right clicking and selecting "Go To Definition).
The full list is:
ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable, ICollection, ISerializable, IDeserializationCallback, IReadOnlyCollection<T>
at 4.5 it only implements:
ISet<T>, ICollection<T>, IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback
If the documentation says otherwise, then (I'm afraid) the documentation is wrong.