/* Итератор
Предоставляет способ последовательного
доступа к множеству, независимо от его
внутреннего устройства
*/
class Program
{
public static void Main(string[] args)
{
#region Пример №1 - базовое
Library library = new Library();
Reader reader = new Reader();
reader.SetBooks(library);
Console.ReadKey();
#endregion
#region Пример №2 - пример работы стека
DataStack stack = new DataStack();
for (int i = 0; i < 5; i++)
stack.Push(i);
DataStack stackCopy = new DataStack(stack);
Console.WriteLine(stack == stackCopy); //true
stackCopy.Push(10);
Console.WriteLine(stack == stackCopy); //false
#endregion
}
}
///
/// Читатель
///
class Reader
{
public void SetBooks(Library library)
{
IBookIterator iterator = library.CreateNumerator();
while(iterator.HasNext())
{
Book book = iterator.Next();
Console.WriteLine(book.Name);
}
}
}
///
/// Поведение поиска библиотеки
///
interface IBookIterator
{
bool HasNext();
Book Next();
}
///
/// Поведение библиотеки
///
interface IBookNumerable
{
IBookIterator CreateNumerator();
int Count { get; }
Book this[int index] { get; }
}
///
/// Класс книги
///
class Book
{
public string Name { get; set; }
}
///
/// Класс библиотеки книг
///
class Library : IBookNumerable
{
private Book[] Books { get; set; }
public Library()
{
Books = new Book[]
{
new Book(){ Name = "James"},
new Book(){ Name = "Karl"},
new Book(){ Name = "Rogan"}
};
}
///
/// Вызов книги
///
/// индекс в библиотеке
/// Book
public Book this[int index] => Books[index];
///
/// Количество книг в библиотеке
///
public int Count => Books.Length;
///
/// Перейти к следующей библиотеке
///
/// IBookIterator(LibraryNumenator)
public IBookIterator CreateNumerator() => new LibraryNumenator(this);
}
class LibraryNumenator : IBookIterator
{
IBookNumerable Aggregate { get; set; }
int index = 0;
///
/// Передача коллекции книг в Library
///
///
public LibraryNumenator(IBookNumerable bookNumerable)
{
Aggregate = bookNumerable;
}
public bool HasNext() => index < Aggregate.Count;
public Book Next() => Aggregate[index++];
}
///
/// Класс стека данных
///
public class DataStack
{
private int[] items = new int[10];
///
/// Длинна массива данных в этом стеке
///
private int lenght;
public DataStack() => lenght = -1;
///
/// Для копирования экземпляра класса
///
/// Экземпляр данного класса
public DataStack(DataStack myStack)
{
this.items = myStack.items;
this.lenght = myStack.lenght;
}
///
/// Свойство геттера для поля items
///
public int[] Items { get => items; }
///
/// Свойство геттера для поля lenght
///
public int Lenght { get => lenght; }
///
/// Добавление элементов в массив
///
/// значение
public void Push(int value) => items[++lenght] = value;
///
/// Получение последнего элемента
///
/// значение
public int Pop() => items[lenght--];
///
/// Переопределение оператора сравнения двух экземпляров данного класса
///
///
///
/// bool
public static bool operator ==(DataStack left, DataStack right)
{
StackIterator it1 = new StackIterator(left),
it2 = new StackIterator(right);
while (it1.IsEnd() || it2.IsEnd())
{
if (it1.Get() != it2.Get()) break;
it1++;
it2++;
}
return !it1.IsEnd() && !it2.IsEnd();
}
///
/// Переопределение оператора сравнения двух экземпляров данного класса
///
///
///
/// bool
public static bool operator !=(DataStack left, DataStack right)
{
StackIterator it1 = new StackIterator(left),
it2 = new StackIterator(right);
while (it1.IsEnd() || it2.IsEnd())
{
if (it1.Get() != it2.Get()) break;
it1++;
it2++;
}
return !it1.IsEnd() && !it2.IsEnd();
}
}
///
/// Перечислитель
///
class StackIterator
{
private DataStack stack;
private int index;
///
/// Инициализируем поля перечислителя
///
/// данные
public StackIterator(DataStack dataStack)
{
this.stack = dataStack;
this.index = 0;
}
///
/// Переопределение опреатора инкрементирования
///
/// новый переданный экземпляр класса
/// экземпляр класса с инкрементированым значением index
public static StackIterator operator ++(StackIterator s)
{
s.index++;
return s;
}
///
/// Возвращает значение элемента поля стека
/// через его свойство по текущему индексу
///
///
public int Get()
{
if(index < stack.Lenght) return stack.Items[index];
return 0;
}
///
/// Возвращет true при достижении предельного размера стека
///
/// bool
public bool IsEnd() => index != stack.Lenght + 1;
}