- Автор темы
- #1
Интерфейс IEnumerable.
В прошлом уроке вы узнали, что такое интерфейсы, поделили их на пользовательские и на встроенные в библиотеку .NET Framework(например, ICloneable). Сейчас настало время познакомиться с ещё двумя стандартными интерфейсами IEnumerable,IEnumerator. Для понимания, зачем они нужны, смоделируем ситуацию. Предположим, есть некий класс Shop(в переводе на русский - магазин) в нем внутри есть массив объектов Radio (то есть массив радиоприёмников). Наверняка было бы достаточно удобно обращаться к внутренним объектам Radio внутри класса Shop, используя конструкцию foreach.Например, так:
Однако при попытке откомпилировать такую программу возникнет ошибка компиляции, которая скажет, что мы не реализовали метод GetEnumerator интерфейса IEnumerable, который находится в пространстве имен System.Collections. Для её решения придется класс Shop отнаследовать от интерфейса IEnumerable (используется для прохода по коллекции) и создать тело для требуемого метода. После изменения получим:
После этого foreach уже будет компилироваться, но для того чтобы проход по Radio состоялся нужно реализовать методы интерфейса IEnumerator, которые неявно будут вызываться при выполнении foreach.В интерфейсе IEnumerator всего 2 метода и 1 свойство.
Методы
Свойство
Наш класс - контейнер обязан реализовать указанные выше методы и свойства. Рассмотрим программу, показывающую данный принцип:
В прошлом уроке вы узнали, что такое интерфейсы, поделили их на пользовательские и на встроенные в библиотеку .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();
}
}