Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Интерфейс IEnumerable.

В прошлом уроке вы узнали, что такое интерфейсы, поделили их на пользовательские и на встроенные в библиотеку .NET Framework(например, ICloneable). Сейчас настало время познакомиться с ещё двумя стандартными интерфейсами IEnumerable,IEnumerator. Для понимания, зачем они нужны, смоделируем ситуацию. Предположим, есть некий класс Shop(в переводе на русский - магазин) в нем внутри есть массив объектов Radio (то есть массив радиоприёмников). Наверняка было бы достаточно удобно обращаться к внутренним объектам Radio внутри класса Shop, используя конструкцию foreach.Например, так:

using System;
class Radio{
 .....
}
class Shop{
    private Radio[]arr;	
    public Shop(){
 	arr = new Radio[2];
	arr[0] = new Radio("Sony",300);
	arr[1] = new Radio("Samsung",200);
	..................
    }
}
class Sample{
  public static void Main(){
	Shop arr = new Shop();
	foreach(Radio r in arr){
	   r.Sound();
	}
	.......
  }
}

Однако при попытке откомпилировать такую программу возникнет ошибка компиляции, которая скажет, что мы не реализовали метод GetEnumerator интерфейса IEnumerable, который находится в пространстве имен System.Collections. Для её решения придется класс Shop отнаследовать от интерфейса IEnumerable (используется для прохода по коллекции) и создать тело для требуемого метода. После изменения получим:

// отнаследовали от IEnumerable
class Shop:IEnumerable{
    private Radio[]arr;	
    public Shop(){
 	arr = new Radio[2];
	arr[0] = new Radio("Sony",300);
	arr[1] = new Radio("Samsung",200);
	..................
    }
    // метод, который возвращает нумератор для прохода 
    // по коллекции объектов Radio
    public IEnumerator GetEnumerator(){
	return (IEnumerator)this
    }
}

После этого foreach уже будет компилироваться, но для того чтобы проход по Radio состоялся нужно реализовать методы интерфейса IEnumerator, которые неявно будут вызываться при выполнении foreach.В интерфейсе IEnumerator всего 2 метода и 1 свойство.

Методы

bool MoveNext();// переход на следующий элемент коллекции
void Reset();// переход на начало коллекции. 
Под коллекцией подразумевается набор элементов какого - типа

Свойство

object Current {get;} // возвращает значение текущего элемента коллекции

Наш класс - контейнер обязан реализовать указанные выше методы и свойства. Рассмотрим программу, показывающую данный принцип:

using System;
using System.Collections;
class Book
{
	private string title;
	private string author;
	private double price;
	public void EnterBook(){
		Console.WriteLine("\nВведите название Книги:");
		title = Console.ReadLine();
		Console.WriteLine("\nВведите автора:");
		author = Console.ReadLine(); 
		Console.WriteLine("\nВведите цену книги:");
		price = Convert.ToDouble(Console.ReadLine());
	}
	public Book(string title,string author,double price)
	{
		this.title = title;
		this.author = author;
		this.price = price;
	}
	public Book()
	{
		this.title = "Безыимянный";
		this.author = "Иван Петров";
		this.price = 0;
	}
	
	public string Title
	{
		get
		{
			return title;
		}
		set
		{
			title = value;
		}
	}
	public string Author
	{
		get
		{
			return author;
		}
		set
		{
			author = value;
		}
	}
	public double Price
	{
		get
		{
			return price;
		}
		set
		{
			price = value;
		}
	}
	public void Print(){
		Console.WriteLine("Автор:{0} Название Книги:{1} Цена:{2}",author,title,price);
	}
}

class Library:IEnumerable,IEnumerator // наследование от  обоих интерфесов
{
	private Book[] obj;
	private string address;
	private string name;
	int curpos = -1; // индекс текущей позиции в массиве книг
	public Library()
	{
		address = "Украина,город Одесса, улица Троицкая 4";
		name = "Библиотека Дружбы Народов";
		obj = new Book[1];
		obj[0] = new Book("Война и Мир","Лев Толстой",50);
	}
	public Library(string address,string name,int len)
	{
		this.address = address;
		this.name = name;
		obj = new Book[len];
		for(int i = 0;i<obj.Length;i++)
		{
			obj[i] = new Book();
		}
	}
	public float QuantityOfBooks
	{
		get
		{
			return obj.Length;
		}
	}
	public string Address
	{
		get
		{
			return address;
		}
		set
		{
			address = value;
		}
	}
	public string Name
	{
		get
		{
			return name;
		}
		set
		{
			name = value;
		}
	}
	public void EnterBooks()
	{
		for(int i = 0;i<obj.Length;i++)
		{
			obj[i].EnterBook();
		}
	}
	public void ShowBooks()
	{
		for(int i = 0;i<obj.Length;i++)
		{
			obj[i].Print();
		}
	}
	public IEnumerator GetEnumerator(){ // возврат нумератора для доступа к коллекции
		return (IEnumerator)this;
	}
	public void Reset(){
		curpos = -1; // установка текущей позиции на начало массива книг!!!
	}
	public object Current{ // Возврат текущей книги из массива книг
		get{
			return obj[curpos];
		}
	}
	public bool MoveNext(){// переход на следующий элемент в коллекции
	    
		if(curpos<obj.Length-1){
			curpos++;
			return true;
		}
		return false;
	}
	
}
class Sample
{
    enum Cars{Opel,BMW,Mercedes,Ford};	
	static void Main()
	{
		
		try
		{
		
			Library lib = new Library("Украина,город Одесса, улица Большая Арнаутская 78",
"Библиотека имени Остапа Бендера",2); lib.EnterBooks(); foreach(Book b in lib) { b.Print(); } lib.Reset(); Console.WriteLine("\n\n\n"); foreach(Book b1 in lib) { b1.Print(); } } catch(Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } }


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru