Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

namespace MiInterfaceHierarchy

{

class Square : IShape

{

// Использование явной реализации для устранения

// конфликта имен членов.

void IPrintable.Draw

{

// Вывести на принтер...

}

void IDrawable.Draw

{

//
Вывести на экран...

}

public void Print

{

// Печатать...

}

public int GetNumberOfSides => 4;

}

}

В идеале к данному моменту вы должны лучше понимать процесс определения и реализации специальных интерфейсов с применением синтаксиса С#. По правде говоря, привыкание к программированию на основе интерфейсов может занять определенное время, так что если вы находитесь в некотором замешательстве, то это совершенно нормальная реакция.

Однако имейте в виду, что интерфейсы являются фундаментальным аспектом .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
). Вот определение этого стандартного интерфейса:

// Данный интерфейс информирует вызывающий код о том,

// что элементы объекта могут перечисляться

public interface IEnumerable

Поделиться с друзьями: