When to Use Delegates Instead of Interfaces



Both delegates and interfaces enable a class designer to separate type declarations and implementation. A given interface can be inherited and implemented by any class or struct. A delegate can be created for a method on any class, as long as the method fits the method signature for the delegate. An interface reference or a delegate can be used by an object that has no knowledge of the class that implements the interface or delegate method. Given these similarities, when should a class designer use a delegate and when should it use an interface?

Use a delegate in the following circumstances:

· An eventing design pattern is used.

· It is desirable to encapsulate a static method.

· The caller has no need to access other properties, methods, or interfaces on the object implementing the method.

· Easy composition is desired.

· A class may need more than one implementation of the method.

Use an interface in the following circumstances:

· There is a group of related methods that may be called.

· A class only needs one implementation of the method.

· The class using the interface will want to cast that interface to other interface or class types.

· The method being implemented is linked to the type or identity of the class: for example, comparison methods.

One good example of using a single-method interface instead of a delegate is IComparable or the generic version, IComparable<(Of <(T>)>). IComparable declares the CompareTo method, which returns an integer that specifies a less than, equal to, or greater than relationship between two objects of the same type. IComparable can be used as the basis of a sort algorithm. Although using a delegate comparison method as the basis of a sort algorithm would be valid, it is not ideal. Because the ability to compare belongs to the class and the comparison algorithm does not change at run time, a single-method interface is ideal.

 


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

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

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

· Используется шаблон разработки событий.

· Желательно инкапсулировать статический метод.

· Вызывающему не требуется доступ к другим свойствам, методам или интерфейсам объекта для реализации метода.

· Желательно простое построение.

· Классу может потребоваться несколько реализаций метода.

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

· Существует группа связанных методов, которые могут быть вызваны.

· Классу потребуется только одна реализация метода.

· Класс, использующий интерфейс, будет передавать этот интерфейс другим типам классов и интерфейсов.

· Реализуемый метод связан с типом или идентификатором класса: например, методы сравнения.

Хорошим примером использования интерфейса с одним методом вместо делегата является 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


Дата добавления: 2019-03-09; просмотров: 214; Мы поможем в написании вашей работы!

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






Мы поможем в написании ваших работ!