Wednesday, June 11, 2014

When & why to use delegates?

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 instantiate, 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).

source: 
http://stackoverflow.com/questions/2019402/when-why-to-use-delegates

No comments:

Post a Comment

Code Formater

Paste Here Your Source Code
Source Code Formatting Options
1) Convert Tab into Space :
2) Need Line Code Numbering :
3) Remove blank lines :
4) Embeded styles / Stylesheet :
5) Code Block Width :
6) Code Block Height :
7) Alternative Background :
Copy Formatted Source Code
 
Preview Of Formatted Code