C# ICollection上的元素(索引)<;T>;

C# ICollection上的元素(索引)<;T>;,c#,linq,extension-methods,indexer,C#,Linq,Extension Methods,Indexer,作为一个头脑清醒的人,我现在正在学习C#,当我遇到这个障碍时,我正在阅读一本教科书 如何从IEnumerable调用ElementAt? 第二条评论 所以问题提到了它,但我只是得到了一个错误 他们也提到做得很好,但他们没有告诉你怎么做 如果我遗漏了一些基本信息,以下是我的代码: 而不是: Deck deck = new Deck(); Card c1 = null; foreach (Card card in deck.Cards){ if (condition for the ind

作为一个头脑清醒的人,我现在正在学习C#,当我遇到这个障碍时,我正在阅读一本教科书

如何从
IEnumerable
调用
ElementAt
? 第二条评论 所以问题提到了它,但我只是得到了一个错误

他们也提到做得很好,但他们没有告诉你怎么做

如果我遗漏了一些基本信息,以下是我的代码:

而不是:

Deck deck = new Deck();
Card c1 = null;
foreach (Card card in deck.Cards){
    if (condition for the index)
         c1 = card;
}
我这样做是对的还是我遗漏了什么?谢谢你的意见

如果要使用Linq,请确保在文件顶部包含
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); }
    }
}
使用System.Collections.Generic;
使用System.Linq;//使用Linq扩展方法需要此行
类卡{}
甲板
{
公共ICollection卡{get;private set;}
公共卡此[整数索引]
{
获取{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); }
    }
}
使用System.Collections.Generic;
类卡{}
甲板
{
公共ICollection卡{get;private set;}
公共卡此[整数索引]
{
get{return System.Linq.Enumerable.ElementAt(Cards,index);}
}
}

它被称为扩展方法

确保引用了
System.Linq

然后只需做
Cards.ElementAt(index)

也许您想使用一个具有索引器的
IList

简单的回答是,您应该将“Deck”声明为:IList(或数组…对于本次讨论基本相同)

“更长”的答案在于“什么是ICollection”。。。ICollection是 (1) 具有已知计数但没有已知(或保证)顺序的IEnumerable。 (假设一个数据存储知道计数,但在读取数据之前不确定顺序。) -或- (2) 一种抽象,其中您知道计数并拥有已知或可靠的顺序,但自然不具有随机访问权。。。堆栈或队列

次要的区别是使用索引(intn)表示#2是O(1)(非常快),但O(n)(较慢)不是O(1)表示#1


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

您会得到什么错误?您不能,内部机制总是使用一些
枚举器,您不能直接跳到元素并获取它。当然,当您调用
ToList
或类似的方法时,您实际上会对其进行一次迭代。我得到的错误是,它找不到definition@KingKing当然,如果
Cards
实际上是一个
IList
ElementAt
仍将使用它的索引器。@p.s.w.g看起来OP的卡是icollection,如果它还实现了IList,那也没关系。谢谢,我想我知道扩展方法是如何工作的,但我想我必须更详细地研究它
Deck deck = new Deck();
Card c1 = null;
foreach (Card card in deck.Cards){
    if (condition for the index)
         c1 = card;
}
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); }
    }
}