【问题标题】:Cast IList to List将 IList 转换为列表
【发布时间】:2010-02-05 13:06:28
【问题描述】:

我正在尝试将 IList 类型转换为 List 类型,但每次都会出错。

List<SubProduct> subProducts= Model.subproduct;

Model.subproduct 返回IList&lt;SubProduct&gt;

【问题讨论】:

  • 最好针对接口(IList)而不是实现(List)进行编程。去List是一个不需要的演员。现在,如果 IList 的实现(不是 List)进入该代码路径,您现在必须添加错误处理。
  • 是的,但是IList 没有List 拥有的东西,例如AddRange

标签: c# list casting ilist


【解决方案1】:

试试

List<SubProduct> subProducts = new List<SubProduct>(Model.subproduct);

List<SubProduct> subProducts = Model.subproducts as List<SubProduct>;

【讨论】:

  • 这是正确的答案,但是您是否有理由要处理 List 而不是 IList?大多数时候使用 IList 是更好的选择。
  • IList subProducts= Model.subproduct;
  • @KeithRousseau 我在需要使用 AddRange() 方法时遇到了问题。
  • 第二个选项不安全,因为它假定Model.subproducts 已经是List&lt;SubProduct&gt; 类型。如果是IList&lt;SubProduct&gt;的不同实现,比如ReadOnlyCollection&lt;SubProduct&gt;,它会默默地返回null,很可能会在后面的程序执行中造成非常混乱的NullReferenceException。真的,如果我们知道它总是会是 List&lt;T&gt;,那么首先返回 IList&lt;T&gt; 有什么意义?
【解决方案2】:

这个怎么样:

List<SubProduct> subProducts = Model.subproduct.ToList();

【讨论】:

  • 请注意 ToList() 创建的副本可能会影响性能和内存。
【解决方案3】:

就我而言,我不得不这样做,因为没有可用的建议解决方案:

List<SubProduct> subProducts = Model.subproduct.Cast<SubProduct>().ToList();

【讨论】:

    【解决方案4】:
    List<SubProduct> subProducts= (List<SubProduct>)Model.subproduct;
    

    隐式转换失败,因为List&lt;&gt; 实现了IList,反之亦然。所以你可以说IList&lt;T&gt; foo = new List&lt;T&gt;(),但不能说List&lt;T&gt; foo = (some IList-returning method or property)

    【讨论】:

      【解决方案5】:
      List<ProjectResources> list = new List<ProjectResources>();        
      IList<ProjectResources> obj = `Your Data Will Be Here`;
      list = obj.ToList<ProjectResources>();
      

      这会将 IList 对象转换为列表对象。

      【讨论】:

        【解决方案6】:

        其他答案都建议将 AddRange 与 IList 一起使用。

        避免强制转换的更优雅的解决方案是实现 IList 的扩展来完成这项工作。

        在 VB.NET 中:

        <Extension()>
        Public Sub AddRange(Of T)(ByRef Exttype As IList(Of T), ElementsToAdd As IEnumerable(Of T))
           For Each ele In ElementsToAdd
              Exttype.Add(ele)
           Next
        End Sub
        
        

        在 C# 中:

        public void AddRange<T>(this ref IList<T> Exttype, IEnumerable<T> ElementsToAdd)
        {
            foreach (var ele in ElementsToAdd)
            {
                Exttype.Add(ele);
            }
        }
        

        【讨论】:

          【解决方案7】:

          如果你有一个包含接口的 IList,你可以这样转换它:

          列出到 IList

          List<Foo> Foos = new List<Foo>(); 
          IList<IFoo> IFoos = Foos.ToList<IFoo>();
          

          列表到列表

          IList<IFoo> IFoos = new List<IFoo>();
          List<Foo> Foos = new List<Foo>(IFoos.Select(x => (Foo)x));
          

          这假定Foo 具有IFoo 接口。

          【讨论】:

            【解决方案8】:
                public async Task<List<TimeAndAttendanceShift>> FindEntitiesByExpression(Expression<Func<TimeAndAttendanceShift, bool>> predicate)
                {
                    IList<TimeAndAttendanceShift> result = await _dbContext.Set<TimeAndAttendanceShift>().Where(predicate).ToListAsync<TimeAndAttendanceShift>();
            
                    return result.ToList<TimeAndAttendanceShift>();
                }
            

            【讨论】:

              【解决方案9】:

              这是将通用对象列表转换/转换为字符串列表的最佳选择。

              object valueList;
              List<string> list = ((IList)valueList).Cast<object>().Select(o => o.ToString()).ToList();
              

              【讨论】:

              • valueList 必须是对象列表
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-11-02
              • 2023-04-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多