我有一个例程
public void SomeRoutine(Listlist) { ... }
然后我尝试调用这个例程
Listlist = new List (); list.Add(Guid.NewGuid()); SomeRoutine(list);
并且它因编译时错误而失败.System.Guid实现了IFormattable,但我得到的错误是
无法从'System.Collections.Generic.List'转换为'System.Collections.Generic.List'
注意:如果您只使用Guids数组,则会出现相同的错误.泛型不是原因....
但!鉴于这种
public void SomeRoutine2(IFormattable obj) { ... }
还有这个
Guid a = Guid.NewGuid(); SomeRoutine2(a);
它汇编!所以问题是为什么?为什么我能够将Guid对象(实现IFormattable)传递给接受IFormattable对象的例程,但是当我尝试将其扩展到集合(通用列表,数组或其他任何东西)时,我得到了转换错误?
我有一段时间找到答案,我认为这将是最好的去处.
这是每个人都在谈论的整个协方差事.它将在.NET 4.0中运行.
见:http://blogs.msdn.com/charlie/archive/2008/10/28/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx
更多阅读:
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-的-fruit.aspx
这是一个经典的泛型用例; 尝试:
public static void SomeRoutine(IList list) where T : IFormattable { ... }
现在SomeRoutine
你可以访问所有IFormattable
成员,但它可以使用:
Listlist; ... SomeRoutine(list); // note no need to specify T
编辑:我还在博客上讨论了此方案的4.0协方差和泛型之间的差异.