【问题标题】:ElementAt(index) on ICollection<T>ICollection<T> 上的 ElementAt(index)
【发布时间】:2013-11-16 00:36:43
【问题描述】:

提醒一下,我目前正在学习 C#,遇到这个障碍时正在阅读教科书。

如何从IEnumerable&lt;T&gt; 调用ElementAtthis中的第二条评论 SO question提到它,但我只是得到一个错误。

Here 他们也提到了这样做,但他们没有告诉你如何

如果我缺少一些基本的东西,这是我的代码:

using System.Collections.Generic;

class Card {}

class Deck
{
    public ICollection<Card> Cards { get; private set; }

    public Card this[int index]
    {
        get { return Cards.ElementAt(index); }
    }
}

我从MSDN Library page 上获得的信息中求助于这个:

class Deck
{
    public ICollection<Card> Cards { get; private set; }

    public Card this[int index]
    {
        get {
        return System.Linq.Enumerable.ElementAt<Card>(Cards, index); 
        }
    }
}

所有这些都来自关于集合的部分以及我展示的第二个代码实现如何更容易地从列表中获取特定元素,而不必遍历枚举器。

Deck deck = new Deck();
Card card = deck[0];

代替:

Deck deck = new Deck();
Card c1 = null;
foreach (Card card in deck.Cards){
    if (condition for the index)
         c1 = card;
}

我这样做是对的还是我错过了什么?感谢您的任何意见!

【问题讨论】:

  • 你得到什么错误?
  • 你不能,内部机制总是使用一些Enumerator,你不能直接跳转到一个元素并获取它。当然,当你调用ToList 或者类似的方法时,你实际上是迭代了一次
  • 我得到的错误是它找不到定义
  • @KingKing 当然,如果Cards 实际上是IListElementAt 无论如何都会使用它的索引器。
  • @p.s.w.g 貌似OP的卡是icollection,如果也实现了IList就OK了。

标签: c# linq extension-methods indexer


【解决方案1】:

如果您想使用 Linq extension methods,请确保在文件顶部包含 System.Linq 命名空间:

using System.Collections.Generic;
using System.Linq; // This line is required to use Linq extension methods

class Card {}

class Deck
{
    public ICollection<Card> Cards { get; private set; }

    public Card this[int index]
    {
        get { return Cards.ElementAt(index); }
    }
}

当然,扩展方法只是带有一点语法糖的常规旧方法。你也可以这样称呼他们:

using System.Collections.Generic;

class Card {}

class Deck
{
    public ICollection<Card> Cards { get; private set; }

    public Card this[int index]
    {
        get { return System.Linq.Enumerable.ElementAt(Cards, index); }
    }
}

【讨论】:

    【解决方案2】:

    它被称为扩展方法。

    确保您引用了System.Linq

    那么就做Cards.ElementAt(index)

    也许您想使用带有索引器的IList&lt;T&gt;

    【讨论】:

    • 谢谢,我以为我知道扩展方法是如何工作的,但我想我必须更详细地研究它
    【解决方案3】:

    “简单”的答案是您应该将“Deck”声明为:IList(或 Array ... 本次讨论基本相同。)

    “更长”的答案在于“什么是 ICollection”的混淆...... ICollection 要么 (1) 具有已知计数但没有已知(或保证)顺序的 IEnumerable。 (想象一个知道计数但在您读取数据之前不修复顺序的数据存储。) -或者- (2) 一种抽象,您知道计数并具有已知或可靠的顺序,但自然不具有随机访问...例如:堆栈或队列。

    次要 区别在于 #2 使用 IndexAt(int n) 是 O(1)(非常快),但 #1 是 O(n)(较慢)而不是 O(1)。

    所以,我的结论是,如果你想要随机访问,那么选择你知道支持的数据结构是(IList 或 Array,但不是 ICollection)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-02
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2010-12-05
      • 1970-01-01
      • 2010-12-12
      相关资源
      最近更新 更多