【问题标题】:Why ICollection index does not work when instantiated?为什么 ICollection 索引在实例化时不起作用?
【发布时间】:2010-12-24 22:37:28
【问题描述】:

当我们将参数声明为 ICollection 并将对象实例化为 List 时,为什么我们不能检索索引?即

ICollection<ProductDTO> Products = new List<ProductDTO>();
Products.Add(new ProductDTO(1,"Pen"));
Products.Add(new ProductDTO(2,"Notebook"));

那么,这将不起作用:

ProductDTO product = (ProductDTO)Products[0];

我缺少什么?
[是的,我们可以使用 List 作为声明,它可以工作,但我不想声明为列表,例如:

List&lt;ProductDTO&gt; Products = new List&lt;ProductDTO&gt;();

]

【问题讨论】:

  • 你的意思是Products.Add(new ProductDTO(1,"Pen"));
  • 这是实际的例子吗? List 和 ICollection 都没有用于接受两个参数的 Add 方法的重载?

标签: c# list indexing icollection


【解决方案1】:

使用 LINQ,您可以这样做:

ProductDTO product = (ProductDTO)Products.ElementAt(0);

【讨论】:

    【解决方案2】:

    ICollection 接口没有声明索引器,因此您不能使用索引通过该类型的引用来获取元素。

    您也许可以尝试IList,它增加了一些功能,同时仍然是抽象的。当然,这可能会影响其他设计决策,所以我会仔细研究。

    【讨论】:

    • 当你说设计决策时。你的意思是?使用 IList 或 ICollection 的最佳方法是什么?
    • @Inanikian 没有“最佳”;这取决于上下文。如果您必须使用 IList 中的方法,比如说您需要索引/排序,那么 IList 可能是需要的最佳接口类型。另一方面,如果您只关心计数、添加、删除和枚举项目,但从不按索引,并且不希望对具有索引器和所有其他功能的类强加附加功能的要求IList 暗示你无论如何都不会使用,那么最好只需要你需要的东西,例如,ICollection(或者甚至 IEnumerable,如果你不修改任何东西)。
    【解决方案3】:

    ICollection 没有定义索引器。

    ICollection Non-Generic

    ICollection Generic

    【讨论】:

    • 您的链接指向非泛型 ICollection,您应将其重新指向泛型表单 @msdn.microsoft.com/en-us/library/92t2ye13.aspx
    • @BasicallyMoney 有时只需要简短的回答。
    • 简洁的答案阅读起来会更快。用户不喜欢阅读,记得吗? :)
    【解决方案4】:

    那么这将起作用:

    ProductDTO product = ((IList<ProductDTO>)Products)[0];
    

    原因是编译器评估左值,即'='左侧的变量,以找出它知道的方法和属性可以在编译时访问。这称为静态类型化,通过静态知道成员始终可访问,确保可以在运行时直接访问对象成员。

    【讨论】:

    • 这消除了使用接口提供的抽象的好处:如果稍后将 Products 更改为 List 以外的其他内容,则上面的代码将被破坏,因为它对底层类型进行了假设表演时。
    • 是的,但它修复了 OP 抱怨的单一语句。
    • 你和我对修复这个词有不同的定义! ;-)
    • 你需要再读一遍我的评论:它改变了一个 single 语句。我从来没有说过我解决了问题的原因。你不能总是从外观上称它为铁锹,在编程世界中所谓的 fix
    【解决方案5】:

    基本问题是 ICollection 没有定义索引。对于 List,这是通过 IList 的实现来完成的。

    试试这个:

    IList<ProductDTO> Products = new List<ProductDTO>(); 
    

    或者,当您需要通过索引访问元素时,您可以继续使用 ICollection 并转换为数组:

    ICollection<ProductDTO> Products = new List<ProductDTO>();        
    ProductDTO z = Products.ToArray()[0];
    

    【讨论】:

    • ICollection&lt;&gt; 没有 ToArray 方法 - 只有 List&lt;&gt;。你需要CopyTo
    • 取决于 .net 的版本。 ToArray() 是 3.x .net 框架的扩展方法。
    【解决方案6】:

    使用 Linq,您可以访问 ICollection 中特定索引处的元素,如下所示:

    myICollection.AsEnumerable().ElementAt(myIndex);
    

    【讨论】:

      【解决方案7】:

      您也可以使用扩展方法将其转换为ProductDTO

      的(列表、数组)
      ICollection<ProductDTO> Products = new List<ProductDTO>();
      var productsList = Products.ToList();
      

      那么你可以这样使用它:

      productsList[index]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-22
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-02
        • 2017-09-06
        • 1970-01-01
        相关资源
        最近更新 更多