请注意,我现在正在学习C#,当我遇到这个障碍时,我正在翻阅教科书。
你如何从IEnumerable<T>
中称呼ElementAt
?这里的第二条评论 所以问题提到了它,但我只是得到一个错误。
在这里,他们也提到这样做,但他们没有告诉你怎么做!
如果我缺少一些基本的东西,这是我的代码:
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 库页面上获得的信息中采用了这种方法:
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;
}
我这样做是对的还是我错过了什么?感谢您的任何输入!
如果要使用 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); }
}
}
当然,扩展方法只是带有一点句法糖的常规旧方法。您也可以这样称呼它们:
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.Linq
。
那就做Cards.ElementAt(index)
也许你想使用具有索引器的IList<T>
。
"简单"的答案是你应该将"Deck"声明为:IList(或Array ...这个讨论基本相同。
"更长"的答案在于"什么是ICollection"的困惑......ICollection 是(1) 具有已知计数但没有已知(或保证)顺序的 IEnumerable。(假设数据存储知道计数,但在您读取数据之前不会修复顺序。-或-(2)一种抽象,你知道计数并具有已知或可靠的顺序,但自然没有随机访问......例如:堆栈或队列。
较小的区别是使用 IndexAt(int n) 表示 #2 是 O(1)(非常快),但 O(n)(较慢)不是 O(1) 表示 #1
。所以,我的结论是,如果你想要随机访问,那么选择你知道支持的数据结构(IList或Array,但不是ICollection)。