Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot implicitly convert List<T> to Collection<T>

This is a compiler error (slightly changed for readability).

This one always puzzled me. FxCop tells that this is a bad thing to return List<T> and classes that are derived from Collection<T> should be preferable as return types.

Also, FxCop says that it is OK to use List<T> for internal data storage/manipulation. Ok, I get it, but what I don't get is why the compiler complains about trying to implicitly convert List<T> to Collection<T>. Isn't List<T> more interface-charged and functional? Why prohibit implicit conversion?

And another question that stems from above: is the new List<int>(some collection<int>) constructor expensive?

like image 740
Valentin V Avatar asked Feb 07 '09 19:02

Valentin V


3 Answers

Why not just do the following:

Collection<string> collection = new Collection<string>(theList); 

as Collection(IList input) takes a List as part of construction.

like image 79
Matthew M. Avatar answered Sep 23 '22 17:09

Matthew M.


List<T> doesn't derive from Collection<T> - it does, however, implement ICollection<T>. That would be a better choice of return type.

As for the new List<int>(some collection<int>) question - it partly depends on what the collection is. If it implements ICollection<T> (at execution time) then the constructor can use its Count property to create the list with the right initial capacity before iterating through it and adding each item. If it doesn't implement ICollection<T> then it's just equivalent to:

List<int> list = new List<int>(); foreach (int x in otherCollection) {     list.Add(x); } 

Still nice to have in a convenient constructor, but not hugely efficient - it can't be, really.

I don't believe the constructor does anything cunning for arrays, which it potentially could - using Array.Copy or whatever to just copy the lot in one go rather than iterating though. (Likewise if it were another List<T> it could get at the backing array and copy that directly.)

like image 36
Jon Skeet Avatar answered Sep 21 '22 17:09

Jon Skeet


List<T> doesn't inherit from Collection<T>. Plain and simple. Unless List<T> provides an operator to implicitly convert to/from Collection<T>, you can't do it. I would actually suggest returning List<T> if you can, as I believe the rules go something like this:

Accept as a parameter the least constrictive interface possible. Return as a return parameter the most constrictive type possible.

like image 21
David Morton Avatar answered Sep 22 '22 17:09

David Morton