I have a routine
public void SomeRoutine(List<IFormattable> list) { ... }
I then try to call this routine
List<Guid>list = new List<Guid>(); list.Add(Guid.NewGuid()); SomeRoutine(list);
And it fails with a compile-time error. System.Guid implements IFormattable, but the error I get is
cannot convert from ‘System.Collections.Generic.List’ to ‘System.Collections.Generic.List’
NOTE: You will get the same error if you just use an array of Guids. Generics is NOT the cause….
But! Given this
public void SomeRoutine2(IFormattable obj) { ... }
and this
Guid a = Guid.NewGuid(); SomeRoutine2(a);
It compiles! So the question is WHY? Why am I able to pass a Guid object (which implements IFormattable) into a routine that accepts an object of IFormattable, but when I try to expand that to a collection (a generic list, or an array, or anything else), I get a conversion error?
I have had a heck of a time finding an answer, and I figured this would be the best place to go.
This is that whole covariance thing everyone talks about. It will work in .NET 4.0.
See here: http://blogs.msdn.com/charlie/archive/2008/10/28/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx
Some more reading:
http://www.infoq.com/news/2008/08/GenericVariance;jsessionid=188695B18864997E8D360E0EEED5983E
http://blogs.msdn.com/lucian/archive/2008/10/02/co-and-contra-variance-how-do-i-convert-a-list-of-apple-into-a-list-of-fruit.aspx