百科问答小站 logo
百科问答小站 font logo



C# 中为什么List<List<T>> 不能转换为 IList<IList<T>> ? 第1页

  

user avatar   rednaxelafx 网友的相关建议: 
      

因为IList<T>的泛型参数T是invariant的,而不是题主所期待的covariant(或者说IList<out T>):

       public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable      

从 List<List<T>> 转成 IList<List<T>> 是完全没问题的,因为这个转换从泛型参数的角度看是invariant的。然而进一步转成 IList<IList<T>> 就不行了,因为把泛型参数中(内层)的 List<T> 转成 IList<T> 需要covariant。

传送门:

Covariance and Contravariance in Generics

具体到题主的例子,其实这样就好了:

       using System.Collections.Generic; using System.Linq;  class Record {   public List<Record> Data {     get { return null; }   } }  class Program {   static void Main(string[] args) {     var records = new List<Record>();     var casted1 = (IList<IList<Record>>)records.Select(r => r.Data as IList<Record>).ToList(); // ok     Console.WriteLine("cast1 succeeded.");     var casted2 = (IList<IList<Record>>)records.Select(r => r.Data).ToList<IList<Record>>(); // ok     Console.WriteLine("cast2 succeeded.");     var casted3 = (IList<IList<Record>>)records.Select(r => r.Data).ToList(); // fail     Console.WriteLine("cast3 succeeded.");   } }      

这是因为我的例子中,ToList()其实是个泛型方法,其泛型参数通常是被自动推导出来的;Record.Data的类型是List<Record>,于是用在那个ToList()调用时推导出来的就是ToList<List<Record>>。我们要么在Select()的时候就as一下来让Select推导出来的类型改变,要么直接在ToList()的地方指定清楚泛型参数,就好啦。




  

相关话题

  C# 和 VB 有多大相似度? 
  如何优化如图所示的,将父类实例扩展为子类实例的代码? 
  Build 2015上微软宣布Windows 10支持Objective-C与Java编写的应用,这对C#与Windows自身有什么长远影响? 
  面向对象中,平行继承体系是否尽量完全抛弃? 
  windows10 界面是用什么语言编写的?.NET在最新的操作系统中有哪些应用 
  ADO.NET的SqlParameter(String, Object)的构造函数第二个参数不能为0? 
  .NET中如何通过Razor引擎生成这样的代码? 
  为什么很多人都说使用微软技术的公司是小公司?是不是微软的技术入门简单? 
  微软开放.net框架源代码后,未来的发展有哪些可期待的? 
  Java为什么选择interface来作为"接口"这个功能的关键字? 

前一个讨论
如何评价@左耳朵耗子 的《关于阿里云经典网络的问题》?
下一个讨论
为什么电子邮件允许冒充发件人?





© 2024-11-21 - tinynew.org. All Rights Reserved.
© 2024-11-21 - tinynew.org. 保留所有权利