←to practical programming

Note "delegates"

Delegates (pointers to functions)

In C-sharp a (pointer to a) function to be passed around is called a delegate. The consept of delegates has evolved substantially with time in Csharp and now the easiest way to work with delegates is to use the generic delegate System.Func (System.Action for functions that do not return anything). For example, the statement
System.Func<double,double> square = delegate(double x){return x*x;}
declares a variable square that references a function that takes a double argument and returns a double (in this particular case the square of its argument). The delegates can be used just as any other type in a C-sharp program.

Functions as arguments

If a function, say make_table_from_0_to_10, expects a function as an argument, it can declare it using System.Func, for example,

static void make_table_from_0_to_10(Func<double,double> f){
	for(double x=0;x<=10;x+=1)WriteLine($"{x} {f(x)}");
}

One can then call make_table_from_0_to_10 as

make_table_from_0_to_10(square);
or
make_table_from_0_to_10(Math.Sin);

Delegates with parameters

The variables in the declaration of a delegate are taken from the current scope as references and can then be used as extra parameters. For example,
double a=0;
Func<double> f = delegate(){ return a; };
a=7;
WriteLine(f()); /* prints 7 */
a=9;
WriteLine(f()); /* prints 9 */

Closures

If a function returns a delegate, then all the variables in the declaration of the delegate are captured by value at the moment of return. The returned object, a delegate with all the captured variables, is called a closure. For example,
public static Func<double> makefun(){
	double a=0;
	Func<double> f = delegate(){a++;return a;};
	return f; /* "a" is captured here */
}