• Добро пожаловать на сайт - Forumteam.digital !

    Что бы просматривать темы форума необходимо зарегестрироваться или войти в свой аккаунт.

    Группа в телеграме (подпишитесь, что бы не потерять нас) - ForumTeam Chat [Подписатся]
    Связь с администратором - @ftmadmin

25. Работаем с интерфейсом IEnumerable.

Redman

<FORUMTEAM>
Команда форума
Регистрация
13.11.17
Сообщения
13.340
Реакции
8.377
Баллы
1.200
FTC
208¢
Интерфейс 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();
    }
}

 
Сверху Снизу