Программирование >>  Программирование с использованием ajax 

1 ... 89 90 91 [ 92 ] 93 94 95 ... 396


Не считая немного отличающегося синтаксиса, подобным образом в коллекцию можно добавлять как новые, так и существующие объекты. После такого добавления элементов их можно перезаписывать с использованием синтаксиса, идентичного тому, что применяется для массивов:

animalArrayList[0] = new Cow( Alma );

В данном примере это, однако, не делается.

В главе 5 было показано, как структура foreach может применяться для итерации по массиву. Подобное возможно потому, что класс System. Array реализует интерфейс lEnumerable, а единственный доступный в этом интерфейсе метод GetEnumerator () позволяет проходить в цикле по элементам коллекции. Более подробно об этом будет рассказываться позже в этой главе. Что касается данного примера, то здесь структура foreach используется для вывода информации о каждом объекте Animal в массиве:

foreach (Animal myAnimal in animalArray) {

Console.WriteLine( New {0} object added to Array collection, +

Name = {1} , myAnimal.ToString (), myAnimal.Name);

Объект ArrayList тоже поддерживает интерфейс lEnumerable и может использоваться со структурой foreach. В этом случае синтаксис выглядит идентично:

foreach (Animal myAnimal in animalArrayList) {

Console.WriteLine( New {0} object added to ArrayList collection, + Name = {1} , myAnimal.ToString (), myAnimal.Name);

Далее для вывода информации о количестве элементов в массиве используется свойство Length:

Console.WriteLine( Array collection contains {0} objects. , animalArray.Length);

Такого же поведения можно добиться и в случае коллекции ArrayList, но только с помощью свойства Count, которое является частью интерфейса ICollection:

Console.WriteLine( ArrayList collection contains {0} objects. , animalArrayList.Count);

От коллекций, будь то простые массивы или более сложные коллекции, мало толку, если они не предоставляют доступа к элементам, которые им принадлежат. Простые массивы являются строго типизированными, т.е. обеспечивают прямой доступ к типу содержащихся в них элементов. Это означает, что методы их элементов можно вызывать напрямую:

animalArray[О].Feed();

В данном случае типом массива является абстрактный класс Animal и поэтому вызывать напрямую методы, предоставляемые производными от него классами, нельзя. Вместо этого нужно использовать синтаксис приведения типов:

( (Chicken)animalArray[1]).LayEgg();

Коллекция ArrayList представляет собой коллекцию объектов System.Object (потому что объекты Animal были присвоены ей посредством полиморфизма). Это означает, что синтаксис приведения в ее случае нужно использовать для всех элементов:

((Animal)animalArrayList[О]) .Feed (); ( (Chicken)animalArrayList[1]).LayEgg();



В остальной части кода иллюстрируются некоторые возможности коллекции ArrayList, которые выходят за рамки таковых в Array. Сначала из коллекции ArrayList можно удалять элементы путем применения методов Remove () и RemoveAt (), которые являются в классе ArrayList частью реализации интерфейса IList. Эти методы позволяют удалять элементы из массива, соответственно, либо на основании ссылки на удаляемый элемент, либо на базе его индекса. В данном примере используется последний метод для удаления первого элемента в списке, каковым является объект Cow, в свойстве Name которого содержится значение Hayley:

animalArrayList.RemoveAt(0);

В качестве альтернативного варианта можно было бы применить и такую строку кода:

animalArrayList.Remove(myCow2) ;

потому что локальная ссылка на этот объект уже имеется (вместо того, чтобы создавать новый объект, в массив с помощью метода Add () была добавлена существующая ссылка). И в том, и в другом случае в коллекции остается один элемент - объект Chicken, к которому получается доступ следующим образом:

((Animal)animalArrayList[0]).Feed();

Любые изменения, вносимые в элементы в объекте ArrayList с оставлением в массиве N элементов, будут осуществляться так, чтобы индексы имели вид от О до N-1. Например, удаление элемента с индексом О приводит к сдвигу всех остальных элементов в массиве на одну позицию, из-за чего доступ к объекту Chicken осуществляется с использованием индекса О, а не 1. Элемента с индексом 1 больше не существует (поскольку изначально этих элементов всего было два), так что использование такой строки, как показана ниже, привело бы к генерации исключения:

((Animal)animalArrayList[1]).Feed();

Еще коллекции ArrayList позволяют добавлять одновременно несколько элементов с помощью метода AddRange (). Этот метод принимает любой объект с интерфейсом ICollection, в том числе и массив animalArray, который был создан ранее в коде:

animalArrayList.AddRange(animalArray);

Чтобы удостовериться в его работоспособности, можно попробовать получить доступ к третьему элементу в коллекции, каковым будет второй элемент в animalArray:

((Chicken)animalArrayList[2]).LayEgg();

Метод AddRange () не является частью предоставляемых ArrayList интерфейсов. Он принадлежит конкретно классу ArrayList и иллюстрирует тот факт, что в классах коллекций можно обеспечивать специализированное поведение, выходящее за рамки того, которого требуют уже рассмотренные интерфейсы. Этот класс предлагает и другие интересные методы, вроде InsertRange (), позволяющего вставлять массив объектов в любой точке в списке, и методов, позволяющих выполнять задачи наподобие сортировки и переупорядочивания массива.

Напоследок иллюстрируются способы извлечения пользы из возможности иметь несколько ссылок на один и тот же объект. Использование метода IndexOf () (который является частью интерфейса IList) позволяет увидеть не только то, что myCowl (объект, который изначально добавлялся в animalArray) теперь является частью коллекции animalArrayList, но и то, как выглядит его индекс:

Console.WriteLine( The animal called {0} is at index {1}. ,

myCowl.Name, animalArrayList.IndexOf(myCowl));



Здесь Add() и Remove () были определены как строго типизированные методы, применяющие для получения доступа к элементам стандартный метод Add () используемого интерфейса IList. Теперь они будут работать только с классами Animal или классами, производными от Animal, что отличается от демонстрировавшихся ранее реализаций ArrayList, где они могли работать с любым объектом.

Класс CollectionBase позволяет использовать синтаксис foreach с производными коллекциями, т.е. например, такой код, как показан ниже:

В качестве расширения данного кода, в двух следующих строках выполняется переименование объекта с помощью ссылки на объект и отображение нового имени на экране с помощью ссылки на коллекцию:

myCowl.Name = Janice ;

Console.WriteLine( The animal is now called {0}. ,

((Animal)animalArrayList[1]).Name);

Определение коллекций

Теперь, когда известно, какие возможности могут предоставлять усовершенствованные классы коллекций, пришла пора научиться создавать свои собственные строго типизированные коллекции. Одним из возможных способов является реализация всех требуемых методов вручную, но это может оказаться очень длинным и сложным процессом. Однако существует и альтернативный вариант, и состоит он в наследовании коллекции от класса, подобного System.Collections .CollectionBase, который является абстрактным классом и предоставляет большую часть реализации коллекции автоматически. Настоятельно рекомендуется использовать именно этот вариант.

Класс CollectionBase поддерживает такие интерфейсы, как lEnumerable, ICollection и IList, но предоставляет лишь часть требуемой для них реализации, а именно - методы Clear () и RemoveAt () для интерфейса IList и свойство Count для интерфейса ICollection. Все остальное, при желании иметь соответствующие функциональные возможности, нужно реализовать самостоятельно.

Для упрощения этого процесса CollectionBase предлагает два защищенных свойства, которые сами обеспечивают доступ к хранимым объектам, а именно - List, которое предоставляет доступ к элементам через интерфейс IList, и InnerList, которое является объектом ArrayList, используемым для хранения элементов.

Например, базовые детали класса коллекции для хранения объектов Animal могли бы определяться следующим образом (более полная реализация будет показана чуть позже):

public class Animals : CollectionBase {

public void Add(Animal newAnimal) List.Add(newAnima1);

public void Remove(Animal oldAnimal) List.Remove(oldAnimal);

public Animals()



1 ... 89 90 91 [ 92 ] 93 94 95 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика