C# Delegates
Delegates
A delegate is a pointer or a reference to a method. Calling the delegate calls the
method. When you Invoke the method, the runtime executes the method.
The delegate keyword creates a delegate type that can then be declared like an
int, string or bool. By assigning the function with the same parameter and return
types, then running the function can be called.
The code below should help explain what I am try to say.
Basic delegate type
Here we are defining the delegate type
// Declare type
public delegate void firstDelegate();
public delegate int unusedDelegate(bool b, float f);
// Declare variable type
static firstDelegate delegateFunc1;
static unusedDelegate delegateUnused;
We create the function with the same delegate types. i.e. Parameters and the return
type.
static void PrintSomething()
{
Console.WriteLine("Print something");
}
static void PrintSomethingElse()
{
Console.WriteLine("Print something else");
}
static int matchUnusedDelegate(bool bolReady, float amountCost)
{
// Only created to show matching parameters and return type of delegate
return 5;
}
We can now assign the function to the delegates and run them
Console.WriteLine("Delegate test for website update");
// Variable contains functon (pointer/reference)
delegateFunc1 = PrintSomething;
// Run delegate
delegateFunc1();
delegateFunc1 = PrintSomethingElse;
delegateFunc1();
Console.ReadKey();
// Multi cast
delegateFunc1 += PrintSomething;
delegateFunc1 += PrintSomething;
delegateFunc1();
Console.ReadKey();
// Delegate returns integer and takes boolean and float parameters
delegateUnused = matchUnusedDelegate;
Console.WriteLine(delegateUnused(false,12.50f));
Lambdas as delegates
Lambdas are types of delegates and can simply replace the functions. These will
then be anonymous functions. These are much smaller in code size, but does have
the disadvantage that they can't be used remove from a multi cast as there is no
reference.
Below are exmples to show the difference from the code above.
// Lambda
delegateFunc1 = () => { Console.WriteLine("From inside a Lambda"); };
delegateFunc1();
Console.ReadKey();
delegateUnused = (bool x, float y) => { return 5; };
Console.WriteLine(delegateUnused(true, 4.99f));
Console.ReadKey();
Action delegate type
The Action delegate is a type that does not have a return value. Everything
else is the same as a normal delegate except that declaring the Action delegate
has only one command instead of two.
// Action delegate - Returns void
static Action firstActionDelegate;
static Action firstActionDelegateWithParam;
// Action delegate
firstActionDelegate = () => { Console.WriteLine("Action with no input parameter"); };
firstActionDelegateWithParam = (int x) => { Console.WriteLine("Number isn't " + x * 2); };
firstActionDelegate();
firstActionDelegateWithParam(2);
Console.ReadKey();
Func delegate type
The Func delegate is a type that does have a return value. Everything
else is the same as a normal delegate except that declaring the Func delegate
has only one command instead of two. The return type is the last parameter in
the declaration.
// Func delegate - Returns value
static Func firstFuncDelegate;
// last type is the return type, i.e. here it's string
static Func firstFuncDeleagteWithBoolParameter;
// Func delegate
firstFuncDelegate = () => { return 33; };
Console.WriteLine(firstFuncDelegate());
firstFuncDeleagteWithBoolParameter = (bool x) => { return Console.WriteLine("Returns a string with value " + x); };
Console.WriteLine(firstFuncDeleagteWithBoolParameter(true));
Console.ReadKey();
Code for the delegate test
Here is the full code used to show how delegates work and the results.
using System;
namespace DelegateTestWeb
{
class Program
{
// Declare type
public delegate void firstDelegate();
public delegate int unusedDelegate(bool b, float f);
// Declare variable type
static firstDelegate delegateFunc1;
static unusedDelegate delegateUnused;
// Action delegate - Returns void
static Action firstActionDelegate;
static Action firstActionDelegateWithParam;
// Func delegate - Returns value
static Func firstFuncDelegate;
// last type is the return type, i.e. here it's string
static Func firstFuncDeleagteWithBoolParameter;
static void Main(string[] args)
{
Console.WriteLine("Delegate test for website update");
// Variable contains functon (pointer/reference)
delegateFunc1 = PrintSomething;
// Run delegate
delegateFunc1();
delegateFunc1 = PrintSomethingElse;
delegateFunc1();
Console.ReadKey();
// Multi cast
delegateFunc1 += PrintSomething;
delegateFunc1 += PrintSomething;
delegateFunc1();
Console.ReadKey();
// Delegate returns integer and takes boolean and float parameters
delegateUnused = matchUnusedDelegate;
Console.WriteLine(delegateUnused(false,12.50f));
// Lambda
delegateFunc1 = () => { Console.WriteLine("From inside a Lambda"); };
delegateFunc1();
Console.ReadKey();
delegateUnused = (bool x, float y) => { return 5; };
Console.WriteLine(delegateUnused(true, 4.99f));
Console.ReadKey();
// Action delegate
firstActionDelegate = () => { Console.WriteLine("Action with no input parameter"); };
firstActionDelegateWithParam = (int x) => { Console.WriteLine("Number isn't " + x * 2); };
firstActionDelegate();
firstActionDelegateWithParam(2);
Console.ReadKey();
// Func delegate
firstFuncDelegate = () => { return 33; };
Console.WriteLine(firstFuncDelegate());
firstFuncDeleagteWithBoolParameter = (bool x) => { return Console.WriteLine("Returns a string with value " + x); };
Console.WriteLine(firstFuncDeleagteWithBoolParameter(true));
Console.ReadKey();
}
static void PrintSomething()
{
Console.WriteLine("Print something");
}
static void PrintSomethingElse()
{
Console.WriteLine("Print something else");
}
static int matchUnusedDelegate(bool bolReady, float amountCost)
{
// Only created to show matching parameters and return type of delegate
return 5;
}
}
}
and the results from Command