logo
CSharp_Prog_Guide

Использование делегатов вместо интерфейсов

И делегаты, и интерфейсы позволяют конструктору классов отделять объявление типов от реализации. Определенный интерфейс может быть унаследован и реализован любым классом или структурой. Делегат может быть создан для метода в любом классе, если метод соответствует сигнатура метода для делегата. Ссылка на интерфейс или делегат могут быть использованы объектом, не имеющим данных о классе, реализующем интерфейс или метод делегата. Учитывая эти сходные признаки, когда в конструкторе классов следует использовать делегат, а когда следует использовать интерфейс?

Делегат следует использовать в следующих ситуациях:

Интерфейс следует использовать в следующих ситуациях:

Хорошим примером использования интерфейса с одним методом вместо делегата является IComparable или более общая версия IComparable<(Of <(T>)>). В IComparable объявляется метод CompareTo, возвращающий целое число, указывающее отношение (меньше, равно или больше) между двумя объектами одинакового типа. Можно использовать IComparable в качестве основы для алгоритма сортировки. В основе алгоритма сортировки можно использовать делегат метода сравнения, но такой подход не является оптимальным. Возможность сравнения относится к классу, а алгоритм сравнения не изменяется при выполнении, поэтому лучше использовать интерфейс с одним методом.

Covariance and Contravariance in Delegates

Covariance and contravariance provide a degree of flexibility when you match method signatures with delegate types. Covariance permits a method to have a more derived return type than what is defined in the delegate. Contravariance permits a method with parameter types that are less derived than in the delegate type.

Example 1 (Covariance)

Description

This example demonstrates how delegates can be used with methods that have return types that are derived from the return type in the delegate signature. The data type returned by SecondHandler is of type Dogs, which derives from the Mammals type that is defined in the delegate.

Code

class Mammals

{

}

class Dogs : Mammals

{

}

class Program

{

// Define the delegate.

public delegate Mammals HandlerMethod();

public static Mammals FirstHandler()

{

return null;

}

public static Dogs SecondHandler()

{

return null;

}

static void Main()

{

HandlerMethod handler1 = FirstHandler;

// Covariance allows this delegate.

HandlerMethod handler2 = SecondHandler;

}

}