3

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.

Kjara
  • 2,504
  • 15
  • 42
  • IReadOnlyCollection exists since .NET 4.5 as far as I know. – Kjara Jul 29 '16 at 10:28
  • `List` is a general class; but for example `LinkedList` is a sub-class for the List class. It may be about inheritance issue, but I want to learn that answer, too. – stuck Jul 29 '16 at 10:32
  • I cannot reproduce this either - perhaps as one clue to us, can you tell us what, specifically, the compiler says as an error or warning? – Damien_The_Unbeliever Jul 29 '16 at 10:38
  • @J.Steen do you have any idea which other options besides the .NET version to use could influence the compiler behaviour? – Kjara Jul 29 '16 at 10:39
  • Just to be sure, it's the Compiler, not the Resharper? – Matthias Müller Jul 29 '16 at 10:39
  • I don't have Resharper installed, so I guess it must be the compiler. – Kjara Jul 29 '16 at 10:42
  • I think it's just vanilla .NET. I have added some libraries, but I am not using them in the above code. – Kjara Jul 29 '16 at 10:46
  • It runs and behaves as expected. That means, I could write `IReadOnlyCollection d = (IReadOnlyCollection)new Queue();` and do not get any runtime exception. – Kjara Jul 29 '16 at 10:50
  • Mb it's work so because there was no direct conversion at Net 4.5 done for those collections? – Shakra Jul 29 '16 at 10:52
  • @J.Steen - I get the same error when I try this even targeting 4.5.2 – ChrisF Jul 29 '16 at 10:52
  • @J.Steen VS 2015, standard console application. If I target 4.6 however, the error disappears. – ChrisF Jul 29 '16 at 10:53
  • 2
    Check out this: http://stackoverflow.com/questions/32762631/cannot-convert-hashset-to-ireadonlycollection/32762752#32762752 – JPhil Jul 29 '16 at 10:59

1 Answers1

2

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.

ChrisF
  • 134,786
  • 31
  • 255
  • 325