Tutorial :What are some common scenarios where delegates should be used? [duplicate]



Question:

This question already has an answer here:

I understand how delegates and events work. I can also imagine some common scenarios where we should implement events, but I’m having harder times understanding in what situations should delegates be used.

thanx

REPLYING TO USER KVB'S POST:

a)

You can basically use delegates wherever you would otherwise use a one-method interface.

I think I somewhat understand the following:

  • Class C could define method C.M, which would take as an argument an interface IM. This interface would define a method IM.A and thus anyone wanting to call C.M would need to implement this interface.

  • Alternatively, method C.M could take ( instead of an interface IM ) as an argument a delegate D with the same signature as method IM.A.

But what I don’t understand is why can’t C.M also use as its parameter a delegate D even if our interface IM defines several other methods besides method A? Thus, the other methods of class C could require as their argument an interface IM, but C.M could instead require a delegate D ( assuming C.M only needs to call method A and not any of the other methods defined within IM ) ?

b)

var list = new List<int>(new[] { 1, 2, 3 });  var item = list.Find(i => i % 2 == 0);  
  • Is the above code an example of what user jpbochi calls ( see hers/his post in this thread ) dependency injection?

  • I assume the above code couldn’t be implemented using events instead of “pure” delegates?


Solution:1

You can basically use delegates wherever you would otherwise use a one-method interface. While this isn't always appropriate, often readability is greatly improved by using delegates instead of interfaces because logic is kept closer to where it is being used. For instance, which of these examples is easier to understand and check for correctness?

var list = new List<int>(new[] { 1, 2, 3 });  var item = list.Find(i => i % 2 == 0);  

As opposed to:

var list = new List<int>(new[] { 1, 2, 3 });  list.Find(new DivisibleBy2Finder());    // Somewhere far away  private class DivisibleBy2Finder : IFinder<int> {      public bool Matches(int i) {          return i % 2 == 0;      }  }  

UPDATE

Let me expand on my answer a bit. Conceptually, delegates are very similar to one-method interfaces with special syntax for invoking the method without using its name (that is, given a delegate D, you can call its method via the syntax D()). There are two other things that make delegates more interesting than one-method interfaces:

  1. You can construct a delegate from a method group. For instance, you can create an Action<string> delegate like this: Action<string> action = new Action<string>(Console.WriteLine);. This creates a delegate that will print its argument to the console when a string is passed to it. Although this allows you to effectively pass methods around, those methods must already have been defined on some class.
  2. You can create an anonymous delegate. To me, this is the key reason that delegates are particularly useful in C#. Some other languages use different constructs to encapsulate a bit of logic at its point of use (e.g. Java has anonymous classes). C# doesn't have anonymous classes, so if you want to create a bit of freestanding logic that can be passed into another method, using an anonymous delegate (or multiple anonymous delegates) is often the best approach in C#. This is what I was trying to illustrate with my example in my original post.

The relationship between events and delegates is a bit tricky. Although it is true that events are implemented in terms of delegates, I'm not sure that is the best way to think about them. Delegates, like instances of other types, can be used in many different contexts; they can be members of a class, they can be passed into methods or returned from methods, they can be stored in local variables within a method, etc. Events, on the other hand, are special members of a class that support the following operations:

  1. Delegates can be added to or removed from the event. These delegates will be called when the event is fired/invoked.
  2. Only within the context of the class where the event is declared, the event can be treated as a standard delegate, meaning that it can be invoked and its invocation list can be inspected/manipulated.

Thus, events are frequently exposed on classes to allow other components to register callbacks, which will be invoked from within the event's class when needed. However, delegates can be used in a much wider variety of situations. Within the Base Class Library, for instance, they are frequently used as arguments to methods to perform generic operations on collections.

Hope that helps to clarify things a bit.


Solution:2

When you want to provide a function, that will be executed on some event. You give to the event's Event handler a delegate of a function that is about to be executed. They are great when you do event driven programming.

Also when you have functions that have functions as arguments (LINQ expressions, predicates, map-functions, aggregate functions, etc). This functions are generally called higher level functions.

In addition you can wrap some functionality, when the caller has no need access other properties, methods, or interfaces on the object implementing the method. In this case it replaces inheritance, somehow.


Solution:3

In my point of view, delegates are the simplest means of dependency injection. When a component receives a delegate (either in an event or in a regular method) it is allowing another component to inject behavior to it.


Solution:4

Implementing callbacks and event listeners.

For example if you have a function that does a remote request (e.g. retrieve a list of your Facebook friends), then you could pass a delegate as final parameter to that function and have it executed once the server response has been received.


Solution:5

asynchronous callbacks are another good example


Solution:6

I use delegates to keep my objects and class libraries loosely coupled.

For example:

  • I have two controls TabControlA and TabControlB on MainForm. Their code resides in separate libraries which are dependencies of MainForm.

  • TabControlA has a public SetShowMessage method that sets a private member called ShowMessage to any delegate (of type Action<string>, say).

  • When MainForm loads, it can get things setup by calling TabControlA.SetShowMessage(TabControlB.PrettyShowingFunction) to wire up (just this part of) TabControlB to (just that part of) TabControlA.

  • Now internally, TabControlA can check if ShowMessage is non-null and call ShowMessage("Hurray, a message that will be displayed on TabControlB!") and now TabControlB.PrettyShowingFunction gets called, allowing TabControlA to communicate with TabControlB, which can display this message.

  • This could be extended to allow TabControlC to do the same thing and show messages on TabControlB, etc.

I didn't know what this was called, but I think it's the the Mediator Pattern. Using Mediator objects you can bundle even more delegates together, for example a progress meter and status label on MainForm, which any control can update.


Solution:7

I like delegates and events (they go hand in hand) for separation of concern (SOC).

What is a delegate? Simply put, a delegate is a type safe method signature. Events basically store a reference to a collection of methods... Events and delegates provide a way to provide out-of-context change notifications to multiple consumers...

Publishers call events and subscribers receive notifications.

How does this work? Here's a quick example.

Let's say your code needs to valid input before processing an order. In a procedural approach, your code (controller) might trigger the 'order' method. Order then validates and then submits or rejects...

In a publisher/subscriber approach, you might have the following events OrderSubmitted, OrderValidated and OrderRejected. Those would be your publishers. You then have a few subscribers, ValidateOrder, CommitOrder and RejectOrder... ValidateOrder would subscribe to OrderSubmitted, CommitOrder subscribes to OrderValidated and finally RejectOrder subscribes to OrderRejected.

As a parameter to your events, you pass in the order. The series of events would then be...

You controller receives an order. The code assumes event null checking is taking place...

void Init()  {      ValidateOrder += SomeValidateMethod;      CommitOrder += SomeCommitMethod;      RejectOrder += SomeRejectMethod;  }    void OrderReceived(Order o)  {    OrderEventArgs OEA = new OrderEventArgs(o);      ValidateOrder(this, OEA);      if (OEA.OrderIsValid)        CommitOrder(this, OEA);    else        RejectOrder(this, OEA);  }  

Just like that, we've got some events. Now, why are we using events/delegates? Let's say the code for rejecting the order updates the database, no problem. Someone says, let's email the client when an order is rejected. Do you need to refactor SomeRejectMethod? No, you can simply create a new method EmailOrderRejected and add it as a subscriber to the RejectOrder event.

This is a very small example, but it really helps when using an event broker for a system as a whole. It helps to decouple dependencies between methods...

I'll try to follow up with some links later, good luck.


Solution:8

Delegates are used to pass comparison functions to generic sort routines; delegates may be used to implement the Strategy Pattern; and delegates are used to invoke asynchronous methods, among other uses.

Edited to add:

This type of comparison between delegates and events doesn't really make any sense, at a certain level. It is like asking why we would need integers when we could mark fields as "public".

An event in C# is nothing more than an access restriction on a field of a delegate type. It says, basically, that another class or object may access the field for additions and removals, but may not inspect the contents of the field or make wholesales changes to the value of the field. But the type of the event is always a delegate, and delegates have many uses that do not require the access restrictions that the event mechanism supplies.


Solution:9

One thing I haven't seen mentioned yet is that delegates make it easy to store methods in data structures. For instance, it's not uncommon for me to find something like this in a functional requirement:

Update all of the relevant sentence records for this charge by setting their status date to the event date. If the charge is disposed with a diversion referral, the relevant sentences are those with a sentence type of "DV", "DCV", or "DVS". If the charge is disposed with a deferred entry of judgment, the relevant sentences are those with a sentence type of "DEJ". Ignore all other charges and sentences.

One way to solve this would be to build a class for sentences and a class for charges and populate them from the data set, and then stick all of the logic above into methods. Another way would be to build a nice big set of nested conditionals.

A third way, which is more in keeping with Steve McConnell's observation that it's easier to debug data than code, is to define a lookup table that contains predicates to use for testing sentence rows:

private static readonly HashSet<string> DiversionTypes =       new HashSet() { "DV", "DCV", "DVS" };  private bool SentenceIsDiversion(DataRow r) { return (DiversionTypes.Contains(r.Field<string>("Type"))); }    private bool SentenceIsDEJ(DataRow r) { return r.Field<string>("Type") == "DEJ"; }    // Map charge disposition codes for diversion and DEJ to predicates that  // test sentence rows for relevance.  Only sentences for charges whose disposition  // code is in this map and who are described by the related predicate should be  // updated.  private static readonly Dictionary<string, Func<DataRow, bool>> DispoToPredicateMap =      new Dictionary<string, Func<DataRow, bool>>  {     { "411211", SentenceIsDiversion },     { "411212", SentenceIsDiversion },     { "411213", SentenceIsDEJ },     { "411214", SentenceIsDEJ },  }  

Which makes the update logic look like this:

string disposition = chargeRow.Field<string>("Disposition");  if (DispoToPredicateMap.ContainsKey(disposition))  {      foreach (DataRow sentenceRow in chargeRow.GetChildRows("FK_Sentence_Charge"))      {         if (DispoToPredicateMap[disposition](sentenceRow))         {            sentenceRow.SetField("StatusDate", eventDate);         }      }  }  

Of the three approaches, this is the hardest to come up with in the first place (or to understand, if you aren't familiar with the technique). But it's much easier to write unit tests that cover 100% of the code, and it's easy to update when the triggering conditions change, too.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »