2013-11-16 2 views
2

Как хэдз-ап, я изучаю C# в данный момент и просматриваю учебник, когда я сталкивался с этим препятствием.ElementAt (index) on ICollection <T>

Как вы узнали о ElementAt из IEnumerable<T>? Второй комментарий в this Вопрос о нем упоминается, но я просто получаю сообщение об ошибке.

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; 
} 

Могу ли я делать это правильно, или я что-то отсутствует? Спасибо за любой вклад!

+0

Какая ошибка вы получаете? –

+0

вы не можете, внутренний механизм всегда использует некоторый 'Enumerator', и вы не можете перейти прямо к элементу и извлечь его. Конечно, когда вы вызываете 'ToList' или какой-то подобный метод, вы на самом деле перебираете его как только –

+0

ошибка, которую я получаю, заключается в том, что она не может найти определение – qdev76

ответ

8

Если вы хотите использовать 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); } 
    } 
} 
+0

спасибо, это сработало – qdev76

1

Он называется методом расширения.

Убедитесь, что у вас есть System.Linq.

Тогда просто сделать Cards.ElementAt(index)

Может быть, вы хотели бы использовать IList<T>, который имеет индексатор.

+0

спасибо, я думал, что знаю, как работают методы расширения, но я думаю, что я должен изучить его более подробно – qdev76

0

«Простой» Ответ в том, что вы должны объявить «Deck», как: (. Или массив ... в принципе то же самое для обсуждения этого вопроса) IList

«Longer» Ответ заключается в смешении «Что является ICollection "... ICollection является либо (1) IEnumerable с известным Count, но NO известным (или гарантированным) заказом. (Представьте себе хранилище данных, которое знает кол-во, но не фиксирует заказ до тех пор, пока вы не прочитаете данные.) -or- (2) абстракция, где вы ЗНАЕТ счет и имеете известный или надежный заказ, но Естественно, не имеют случайного доступа ... например: стек или очередь.

Разница заключается в использовании IndexAt (int n) для # 2 - O (1) (очень быстро), но O (n) (медленнее) NOT O (1) для # 1.

Итак, мой вывод заключается в том, что вы хотите получить произвольный доступ, а затем выбрать структуру данных, которую вы поддерживаете KNOW (IList или Array, но не ICollection).