В идеале к данному моменту вы должны лучше понимать процесс определения и реализации специальных интерфейсов с применением синтаксиса С#. По правде говоря, привыкание к программированию на основе интерфейсов может занять определенное время, так что если вы находитесь в некотором замешательстве, то это совершенно нормальная реакция.
Однако имейте в виду, что интерфейсы являются фундаментальным аспектом .NET Core. Независимо от типа разрабатываемого приложения (веб-приложение, настольное приложение с графическим пользовательским интерфейсом, библиотека доступа к данным и т.п.) работа с интерфейсами будет составной частью этого процесса. Подводя итог, запомните, что интерфейсы могут быть исключительно полезны в следующих ситуациях:
• существует единственная иерархия, в которой общее поведение поддерживается только подмножеством производных типов;
• необходимо моделировать общее поведение, которое встречается в нескольких иерархиях, не имеющих общего родительского класса кроме
System.Object
.
Итак, вы ознакомились со спецификой построения и реализации специальных интерфейсов. Остаток главы посвящен исследованию нескольких предопределенных интерфейсов, содержащихся в библиотеках базовых классов .NET Core. Как будет показано, вы можете реализовывать стандартные интерфейсы .NET Core в своих специальных типах, обеспечивая их бесшовную интеграцию с инфраструктурой.
Интерфейсы IEnumerable и IEnumerator
Прежде чем приступать к исследованию процесса реализации существующих интерфейсов .NET Core, давайте сначала рассмотрим роль интерфейсов
IEnumerable
и
IEnumerator
. Вспомните, что язык C# поддерживает ключевое слово
foreach
, которое позволяет осуществлять проход по содержимому массива любого типа:
// Итерация по массиву элементов.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
Хотя может показаться, что данная конструкция подходит только для массивов, на самом деле
foreach
разрешено использовать с любым типом, который поддерживает метод
GetEnumerator
. В целях иллюстрации создайте новый проект консольного приложения по имени
CustomEnumerator
. Скопируйте в новый проект файлы
Car.cs
и
Radio.cs
из проекта
SimpleException
, рассмотренного в главе 7. Не забудьте поменять пространства имен
для классов на
CustomEnumerator
.
Теперь вставьте в проект новый класс
Garage
(гараж), который хранит набор объектов
Car
(автомобиль) внутри
System.Array
:
using System.Collections;
namespace CustomEnumerator
{
// Garage содержит набор объектов Car.
public class Garage
{
private Car[] carArray = new Car[4];
// При запуске заполнить несколькими объектами Car.
public Garage
{
carArray[0] = new Car("Rusty", 30);
carArray[1] = new Car("Clunker", 55);
carArray[2] = new Car("Zippy", 30);
carArray[3] = new Car("Fred", 30);
}
}
}
В идеальном случае было бы удобно проходить по внутренним элементам объекта
Garage
с применением конструкции
foreach
как в ситуации с массивом значений данных:
using System;
using CustomEnumerator;
// Код выглядит корректным...
Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
Garage carLot = new Garage;
// Проход по всем объектам Car в коллекции?
foreach (Car c in carLot)
{
Console.WriteLine("{0} is going {1} MPH",
c.PetName, c.CurrentSpeed);
}
Console.ReadLine;
К сожалению, компилятор информирует о том, что в классе Garage не реализован метод по имени
GetEnumerator
, который формально определен в интерфейсе
IEnumerable
, находящемся в пространстве имен
System.Collections
.
На заметку! В главе 10 вы узнаете о роли обобщений и о пространстве имен
System.Collections.Generic
. Как будет показано, это пространство имен содержит обобщенные версии интерфейсов
IEnumerable/IEnumerator
, которые предлагают более безопасный к типам способ итерации по элементам.
Классы или структуры, которые поддерживают такое поведение, позиционируются как способные предоставлять вызывающему коду доступ к элементам, содержащимся внутри них (в рассматриваемом примере самому ключевому слову
foreach
). Вот определение этого стандартного интерфейса:
// Данный интерфейс информирует вызывающий код о том,