Reputation: 149
As a heads up, I'm learning C# at the moment and going through a textbook when I ran into this obstacle.
How do you call ElementAt
from an IEnumerable<T>
?
The second comment in this
SO question mentions it, but I just get an error.
Here they mention doing it as well, but they don't tell you how!
In case I'm missing something basic, here's my code:
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); }
}
}
I've resorted to this from the information I got on the 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);
}
}
}
All this comes from the section on collections and how the second code implementation I showed makes it easier to grab a specific element from the list rather than having to iterate through the enumerator.
Deck deck = new Deck();
Card card = deck[0];
Instead of:
Deck deck = new Deck();
Card c1 = null;
foreach (Card card in deck.Cards){
if (condition for the index)
c1 = card;
}
Am I doing this right or am I missing something? Thanks for any input!
Upvotes: 3
Views: 6181
Reputation: 131
The "simple" answer is that you should declare "Deck" as: IList (or Array ... basically the same for this discussion.)
The "Longer" answer lies in the confusion of "What is ICollection" ... ICollection is either (1) an IEnumerable with a known Count but NO known (or guaranteed) order. (Imagine a data-store that knows the count but doesn't fix the order until you read the data.) -or- (2) an abstraction where you KNOW the count and have a known or dependable order, but do NOT naturally have random-access ... eg: a stack or a queue.
The minor difference is using IndexAt(int n) for #2 is O(1) (very fast), but O(n) (slower) NOT O(1) for #1 .
So, my conclusion is if you want random access, then pick data structure that you KNOW supports is (IList or Array, but not ICollection).
Upvotes: 0
Reputation: 190935
It is called an extension method.
Ensure you have System.Linq
referenced.
Then just do Cards.ElementAt(index)
Perhaps you would like to use a IList<T>
which has an indexer.
Upvotes: 1
Reputation: 149020
If you want to use Linq extension methods, make sure you include the System.Linq
namespace at the top of your file:
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); }
}
}
Of course, extension methods are just regular old methods with a little bit of syntactic sugar. You could also call them this way:
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); }
}
}
Upvotes: 9