When to use delegates instead of interfaces

In accordance with this article, it reads:

Use a delegate in the following cases:

  • A class may require more than one method implementation.

Use the interface in the following cases:

  • A class requires only one method implementation.

Can someone explain this to me?

+4
source share
5 answers

A class may require more than one method implementation.

public delegate int PerformCalculation(int x, int y); void SomeMethod() { PerformCalculation PerformCalculation_1 = myDelegateFun_1; PerformCalculation PerformCalculation_2 = myDelegateFun_2; PerformCalculation_1(5, 3); PerformCalculation_2(5, 3); } private int myDelegateFun_1(int x, int y) { return x + y; } private int myDelegateFun_2(int x, int y) { return x + y; } 

In the above example PerformCalculation_1, PerformCalculation_2 is a multiple implementation of PerformCalculation

 A class only needs one implementation of the method 

 interface IDimensions { float Length(); } class Box : IDimensions { float Length() { return lengthInches; } } 

The above example shows only one implementation of the method displayed by the interface.

+3
source

It's ... weird and confusing. If you need only one implementation of a method ... use a method (perhaps a virtual method). As with interfaces, part of the point delegates is that you can replace several different implementations.

If I had to summarize:

the delegate type is very similar to an interface that provides only one method, and the delegate instance is very similar to an instance of a class that implements this interface, just with a lot of compiler secrets to make it very easy to write, i.e. x => 2 * x and without (sometimes) needing an instance.

the delegate also has some other useful event-oriented tricks (multi-cast, etc.), but that sounds unrelated to the context of the article.

+3
source

In my simple head, this is very similar to ICompare / IComparable.

Implementing an interface means that behavior is integral to the implementation class. The behavior does not change based on the caller or the circumstances of the call.

The delegate said that the operation is not an integral part of the class, but based on the context or the caller to determine.

+1
source

This wording seems a bit confusing, but can be illustrated by example. Suppose someone designed a button control that would like to provide a notification when it was pressed. A common practice would be for the button to maintain a list of delegates to call. If a class would like a button to call one of its methods on the instance itself, it can easily build a delegate that will call this method on that instance. Note that using a delegate for this purpose means that you need to create a heap object for the delegate in addition to the instance whose method the delegate should call.

An alternative approach would be to define the INotifyOfButtonClick interface using the NotifyOfButtonClick() method, and control the buttons to save the INotifyButtonClick list. When a button is clicked, it will call NotifyOfButtonClick() for each instance. If the form has only one button that uses this interface, or if all such buttons use the same method, the form can implement INotifyOfButtonClick() itself and add itself to the list of subscription to the button (s), instead of creating a separate delegate to call his method. In scenarios where this approach works, it may be more efficient than using delegates. If there are two buttons on the form that use the same interface, but, however, want to call different methods, things get complicated. In this case, it would be necessary for the form to create a new object, the purpose of which was to implement INotifyOfButtonClick() by calling some method in the form to which it contains a link. Using such wrapper objects is likely to produce performance comparable to delegates, but without the involvement of some delegates providing the compiler.

By the way, if Microsoft can add a nested IInvoke interface to each delegate (for example, Action<int> will determine the Action<int>.IInvoke ), then if the methods that took Action<int> were overwritten to accept Action<int>.IInvoke , then objects that had only one method, which was supposed to be called by such delegates, could simply go to such methods. This feature can improve closing efficiency.

0
source

β€’ An interface defines only one method. β€’ Multicast required. β€’ The subscriber needs to implement the interface several times.

0
source

All Articles