Презентация на тему: Интерфейс IEnumerable

Реклама. Продолжение ниже
Интерфейс IEnumerable
Интерфейс IEnumerable
Интерфейс IEnumerable
Интерфейс IEnumerable
Интерфейс IEnumerable
Интерфейс IEnumerable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
Интерфейсы I С omparer и IComparable
1/13
Средняя оценка: 4.0/5 (всего оценок: 67)
Код скопирован в буфер обмена
Скачать (94 Кб)
Реклама. Продолжение ниже
1

Первый слайд презентации: Интерфейс IEnumerable

Класс, наследующий интерфейс IEnumerable (англ. «Перечислимый»), может участвовать в цикле foreach. В случае с классом Person, использование индексатора позволило обращаться к детям персоны по индексу. Однако попытка их перебора через цикл foreach завершится ошибкой: foreach ( Person ch in p.Children ) Console.WriteLine ( ch.FirstName ); / / Ошибка доступа Поскольку свойство Children представляет класс ArrayList, реализующий интерфейс IEnumerable, то для устранения ошибки достаточно сделать данное свойство открытым ( public ). Однако есть другой способ устранения ошибки – реализовать в самом классе Person интерфейс IEnumerable, содержащий один метод – GetEnumerator (), возвращающий в качестве результата интерфейс IEnumerator (англ. «Счетчик»). Вариант реализации: public IEnumerator GetEnumerator ( ) { return Children. GetEnumerator () ; }

Изображение слайда
1/1
2

Слайд 2: Интерфейс IEnumerable

Поскольку для массива Children (класс ArrayList ) метод GetEnumerator () интерфейса IEnumerable уже реализован, мы воспользовались им для реализации данного метода в классе Person. В результате цикл foreach в приведенном ранее примере начнет работать без ошибок. Следует заметить, что в этом примере мы пошли на хитрость и воспользовались готовой реализацией метода GetEnumerator () из другого класса. Поскольку результат метода GetEnumerator () имеет тип интерфейса IEnumerator, достаточно просто реализовать данный интерфейс и далее вернуть свой вариант реализации. Интерфейс IEnumerator содержит три метода: Current () – метод возвращает текущий элемент списка. MoveNext () – метод осуществляет переход к следующему элементу списка (меняет значение индекса или ссылки, тем самым указывая на новый текущий элемент). Reset () – метод производит сброс счетчика.

Изображение слайда
1/1
3

Слайд 3: Интерфейс IEnumerable

Реализуем интерфейс IEnumerator в отдельном классе PersonEnumerator. public class PersonEnumerator : IEnumerator { int index = - 1 ; Person p ; public PersonEnumerator (Person p) / / Конструктор { this.p = p ; } / / Здесь будет реализация методов интерфейса IEnumerator }

Изображение слайда
1/1
4

Слайд 4: Интерфейс IEnumerable

Опишем в классе реализацию методов интерфейса IEnumerator : public Object Current() / / Возврат текущего элемента { get { return p [ index ] ; } } public bool MoveNext () / / Переход к следующему элементу { index ++; return ( index >= p.GetChildrenNumber () ); } public void Reset() / / Сброс счетчика { index = -1; }

Изображение слайда
1/1
5

Слайд 5: Интерфейс IEnumerable

Теперь следует изменить в классе Person реализацию метода GetEnumerator () : public IEnumerator GetEnumerator ( ) { return new PersonEnumerator ( this ) ; } В результате при вызове конструктор класса PersonEnumerator получает в качестве параметра экземпляр класса Person, для которого становится возможным перебор детей (в том числе в цикле foreach ). Примечание. Возможны различные варианты реализации методов интерфейса IEnumerator. Например, метод MoveNext () может осуществлять обход списка детей в обратном порядке (в этом случае при инициализации и в методе Reset () индекс должен принимать начальное значение, равное количеству детей персоны).

Изображение слайда
1/1
6

Слайд 6: Интерфейс IEnumerable

В C# существует способ реализовать метод GetEnumerator () без реализации методов интерфейса IEnumerator. Для этого используется оператор yield. В этом случае метод GetEnumerator () можно реализовать как: public IEnumerator GetEnumerator ( ) { foreach ( Person ch in Children) yield return ch ; } Здесь в методе GetEnumerator () запускается ещё один цикл foreach, перебирающий все элементы списка Children. Конструкция yield return возвращает полученное значение внешнему итератору (первому циклу foreach ) без прерывания работы метода GetEnumerator (). Замечание. Конструкция yield return не может использоваться внутри блока обработки исключительных ситуаций.

Изображение слайда
1/1
7

Слайд 7: Интерфейсы I С omparer и IComparable

Интерфейсы IComparer и IComparable отвечают за сортировку элементов массива. Для элементов массивов, представляющих простые типы данных, платформа.NET обладает информацией о том, как их сравнивать. Что касается элементов пользовательского типа (классов), то об описании логики их сравнения должен позаботиться сам пользователь-программист. Попробуем описать в классе Person метод упорядочивания детей персоны: public void SortChildren ( ) { Children.Sort () ; } При создании класса Person мы не описывали правил, согласно которым платформа должна сортировать его объекты.

Изображение слайда
1/1
Реклама. Продолжение ниже
8

Слайд 8: Интерфейсы I С omparer и IComparable

В результате мы получим ошибку при попытке вызвать метод: Person p = new Person( "Иван", "Иванов" ) ; p.AddChild ( "Игорь", "Иванов" ) ; p.AddChild ( "Ярослав", "Иванов" ) ; p.AddChild ( "Галина", "Иванов" ) ; p.SortChildren () ; / / Ошибка сравнения двух элементов Для того, чтобы устранить ошибку, следует реализовать в классе интерфейс IComparable, содержащий единственный метод CompareTo (). Данный метод сравнивает вызвавший его объект с объектом, переданным в метод в качестве параметра. В результате метод возвращает число: отрицательное, если текущий объект меньше переданного; ноль, если объекты одинаковы; положительное, если текущий объект больше переданного.

Изображение слайда
1/1
9

Слайд 9: Интерфейсы I С omparer и IComparable

Вариант реализации метода CompareTo () : public int CompareTo (Object o) { Person p = (Person) o ; string Name1 = ToString () ; string Name2 = p.ToString () ; return Name1.CompareTo(Name2) ; } Метод ToString ранее был переопределен нами: public new string ToString () { return FirstName + " " + SecondName ; }

Изображение слайда
1/1
10

Слайд 10: Интерфейсы I С omparer и IComparable

В приведенном примере для организации объектов-персон мы воспользовались возможностями класса string, в котором метод CompareTo () интерфейса IComparable уже был реализован. В результате сортировка массива объектов класса Person была сведена к сортировке получаемых на их основе строк. Если же требуется описать собственный алгоритм сортировки (например, упорядочить объекты по нескольким свойствам различного типа), следует реализовать интерфейс IComparer, у которого имеется единственный метод Compare (), получающий в качестве параметров два объекта, которые требуется сравнить. Возвращаемое методом значение аналогично возвращаемому методом CompareTo (). Возможный вариант реализации метода: public int IComparer.Compare (Object p1, Object p2) { string Name1 = ((Person) p1). ToString () ; string Name2 = ((Person) p2). ToString () ; return Name1.CompareTo(Name2) ; }

Изображение слайда
1/1
11

Слайд 11: Интерфейсы I С omparer и IComparable

Для вызова метода Compare () следует вызвать метод Sort (), в качестве параметра которого должен быть передан объект класса, реализующего интерфейса IComparer. Например, для упорядочивания детей конкретной персоны можно передать в метод Sort () ссылку на этот же объект ( для его класса Person интерфейс IComparer уже был нами реализован) : Children.Sort ( this ) ; Однако в качестве параметра в метод может быть передан любой другой класс. Главное условие – этот класс должен реализовывать интерфейс IComparer и уметь сравнивать объекты класса, вызвавшего метод Sort (). Для иллюстрации данного принципа объявим класс SortTest, который реализует сортировку массива объектов класса Person в обратном порядке.

Изображение слайда
1/1
12

Слайд 12: Интерфейсы I С omparer и IComparable

class SortTest : IComparer { int IComparer.Compare (Object p1, Object p2) { string Name1 = ((Person) p1). ToString () ; string Name2 = ((Person) p2). ToString () ; return Name2.CompareTo(Name1) ; } } В отличие от класса Person, в классе SortTest метод CompareTo () вызывается объектом p2, а в качестве параметра метода используется объект p 1. В результате массив объектов-персон сортируется в обратном порядке.

Изображение слайда
1/1
13

Последний слайд презентации: Интерфейс IEnumerable: Интерфейсы I С omparer и IComparable

Объявленный класс SortTest можно использовать для сортировки в обратном порядке массива детей персоны (которые тоже являются персонами). Для этого массивом Children вызывается метод Sort (), параметром в который передается экземпляр класса SortTest, для которого нами был реализован метод Compare () : Children.Sort ( new SortTest () ) ; Поскольку объект класса SortTest в дальнейшем нам не потребуется, мы обошлись без объявления ссылающейся на него переменной и создали объект-параметр сразу при вызове метода через ключевое слово new.

Изображение слайда
1/1
Реклама. Продолжение ниже