tags:

views:

543

answers:

6

Hi everyone,

I'm relatively new in c#, & I'm wondering when to use Delegates appropriately. they are widely used in events declaration , but when should I use them in my own code and why are they useful?, why not to use something else?

I'm also wondering when I have to use delegates and I have no other alternative.

Thx for the help.

EDIT: I think I've found a necessary use of Delegates here

+1  A: 

I consider delegates to be Anonymous Interfaces. In many cases you can use them whenever you need an interface with a single method, but you don't want the overhead of defining that interface.

Mark Seemann
+1  A: 

Delegates are extremely useful when wanting to declare a block of code that you want to pass around. For example when using a generic retry mechanism.

Pseudo:

function Retry(Delegate func, int numberOfTimes)
    try
    {
       func.Invoke();
    }
    catch { if(numberOfTimes blabla) func.Invoke(); etc. etc. }

Or when you want to do late evaluation of code blocks, like a function where you have some Transform action, and want to have a BeforeTransform and an AfterTransform action that you can evaluate within your Transform function, without having to know whether the BeginTransform is filled, or what it has to transform.

And of course when creating event handlers. You don't want to evaluate the code now, but only when needed, so you register a delegate that can be invoked when the event occurs.

Jan Jongboom
+3  A: 

I agree with everything that is said already, just trying to put some other words on it.

A delegate can be seen as a placeholder for a/some method(s).

By defining a delegate, you are saying to the user of your class "Please feel free to put any method that match this signature here and it will be called each time my delegate is called".

Typical use is of course events. All the OnEventX delegate to the methods the user defines.

Delegates are useful to offer to the user of your objects some ability to customize their behaviour. Most of the time, you can use other ways to achieve the same purpose and I do not believe you can ever be forced to create delegates. It is just the easiest way in some situations to get the thing done.

Benoit Vidis
+1  A: 

Delegates Overview

Delegates have the following properties:

  • Delegates are similar to C++ function pointers, but are type safe.

  • Delegates allow methods to be passed as parameters.

  • Delegates can be used to define callback methods.

  • Delegates can be chained together; for example, multiple methods can be
    called on a single event.

  • Methods don't need to match the delegate signature exactly. For more
    information, see Covariance and
    Contra variance

  • C# version 2.0 introduces the concept of Anonymous Methods, which permit code blocks to be passed as parameters in place of a separately
    defined method.

Lukas Šalkauskas
If you have a C++ then background thinking of them as function pointers is helpful.
jbloomer
A: 

A delegate is a simple class that is used to point to methods with a specific signature, becoming essentially a type-safe function pointer. A delegate's purpose is to facilitate a call back to another method (or methods), after one has been completed, in a structured way.

While it could be possible to create an extensive set of code to perform this functionality, you don’t need too. You can use a delegate.

Creating a delegate is easy to do. Identify the class as a delegate with the "delegate" keyword. Then specify the signature of the type.

Pankaj
A: 

Say you want to write a procedure to integrate some real-valued function f (x) over some interval [a, b]. Say we want to use the 3-Point Gaussian method to do this (any will do, of course).

Ideally we want some function that looks like:

// 'f' is the integrand we want to integrate over [a, b] with 'n' subintervals.
static double Gauss3(Integrand f, double a, double b, int n) {
  double res = 0;

  // compute result
  // ...

  return res;
}

So we can pass in any Integrand, f, and get its definite integral over the closed interval.

Just what type should Integrand be?

Without Delegates

Well, without delegates, we'd need some sort of interface with a single method, say eval declared as follows:

// Interface describing real-valued functions of one variable.
interface Integrand {
  double eval(double x);
}

Then we'd need to create a whole bunch of classes implementing this interface, as follows:

// Some function
class MyFunc1 : Integrand {
  public double eval(double x) {
    return /* some_result */ ;
  }
}

// Some other function
class MyFunc2 : Integrand {
  public double eval(double x) {
    return /* some_result */ ;
  }
}

// etc

Then to use them in our Gauss3 method, we need to invoke it as follows:

double res1 = Gauss3(new MyFunc1(), -1, 1, 16);
double res2 = Gauss3(new MyFunc2(), 0, Math.PI, 16);

And Gauss3 needs to do the look like the following:

static double Gauss3(Integrand f, double a, double b, int n) {
  // Use the integrand passed in:
  f.eval(x);
}

So we need to do all that just to use our arbitrary functions in Guass3.

With Delegates

public delegate double Integrand(double x);

Now we can define some static (or not) functions adhering to that prototype:

class Program {
   static double MyFunc1(double x) { /* ... */ }
   static double MyFunc2(double x) { /* ... */ }
   // ... etc ...

   public static double Gauss3(Integrand f, ...) { 
      // Now just call the function naturally, no f.eval() stuff.
      double a = f(x); 
      // ...
   }

   // Let's use it
   static void Main() {
     // Just pass the function in naturally (well, its reference).
     double res = Gauss3(MyFunc1, a, b, n);
     double res = Gauss3(MyFunc2, a, b, n);    
   }
}

No interfaces, no clunky .eval stuff, no object instantiation, just simple function-pointer like usage, for a simple task.

Of course, delegates are more than just function pointers under the hood, but that's a separate issue (function chaining and events).

Alex