- •Введение
- •Оглавление
- •Общие типы (generics)
- •Типы интерфейсов
- •Типы делегатов
- •Встроенные типы данных
- •Преимущества использования общих типов
- •Интерфейсы вC# Синтаксис интерфейса
- •Реализация интерфейса
- •Использование интерфейсных ссылок
- •Делегаты в c#
- •Описание делегатов
- •Использование делегатов
- •Массивы
- •Использование делегатов вместо интерфейсов
- •Практика
- •Программа 1
- •Программа 2
- •Заключение
- •Литература
Использование делегатов вместо интерфейсов
И делегаты, и интерфейсы позволяют конструктору классов отделять объявление типов от реализации. Определенный интерфейс может быть унаследован и реализован любым классом или структурой. Делегат может быть создан для метода в любом классе, если метод соответствует сигнатуре метода для делегата. Ссылка на интерфейс или делегат могут быть использованы объектом, не имеющим данных о классе, реализующем интерфейс или метод делегата. Учитывая эти сходные признаки, когда в конструкторе классов следует использовать делегат, а когда следует использовать интерфейс?
Делегат следует использовать в следующих ситуациях:
Используется шаблон разработки событий.
Желательно инкапсулировать статический метод.
Вызывающему не требуется доступ к другим свойствам, методам или интерфейсам объекта для реализации метода.
Желательно простое построение.
Классу может потребоваться несколько реализаций метода.
Интерфейс следует использовать в следующих ситуациях:
Существует группа связанных методов, которые могут быть вызваны.
Классу потребуется только одна реализация метода.
Класс, использующий интерфейс, будет передавать этот интерфейс другим типам классов и интерфейсов.
Реализуемый метод связан с типом или идентификатором класса: например, методы сравнения.
Хорошим примером использования интерфейса с одним методом вместо делегата является IComparable или более общая версия IComparable<(Of <(T>)>). В IComparable объявляется метод CompareTo, возвращающий целое число, указывающее отношение (меньше, равно или больше) между двумя объектами одинакового типа. Можно использовать IComparable в качестве основы для алгоритма сортировки. В основе алгоритма сортировки можно использовать делегат метода сравнения, но такой подход не является оптимальным. Возможность сравнения относится к классу, а алгоритм сравнения не изменяется при выполнении, поэтому лучше использовать интерфейс с одним методом.
Практика
Для более полного представления того, что я пыталась описать выше, предлагаю для рассмотрения два примера, где использовалось описание и интерфейсов и делегатов с помощью общих типов.
Задачи составлены аналогично друг другу, отличием является лишь условие поиска в массиве.
А именно:
Поиск заданного элемента в массиве.
Поиск максимального элемента в массиве.
Программа 1
using System;
//интерфейс
public interface IElement
{
void newE();
int summ();
}
//класс реализующий интерфейс
public class MyElement : IElement
{
public string name;
public int e1;
public int e2;
//метод для заполнения элементов класса
public void newE()
{
name = Console.ReadLine();
e1 = Convert.ToInt32(Console.ReadLine());
e2 = Convert.ToInt32(Console.ReadLine());
}
//подсчет суммы элементов
public int summ()
{
return (e1 + e2);
}
}
//описание делегата
delegate int Delegate1(IElement[] arr, int param);
public class Test
{//метод для поиска элемента с заданной суммой в массиве (если его нет - возвращает -1)
static int Find (IElement[] arr, int param)
{ for (int i = 1; i < 5; i ++)
{ if (arr[i].summ() == param)
{return i;} }
return -1;}
public static void Main()
{ Delegate1 d1 = new Delegate1(Find);
IElement[] array1 = new IElement[5];
array1[0] = new MyElement();
array1[0].newE();
array1[1] = new MyElement();
array1[1].newE();
array1[2] = new MyElement();
array1[2].newE();
array1[3] = new MyElement();
array1[3].newE();
array1[4] = new MyElement();
array1[4].newE();
int c = d1(array1,16);
Console.WriteLine("Номер элемента с заданной суммой:");
Console.WriteLine(c); }
}