Delegate is similar to function pointer. It is a reference type, but instead of referring to an object, it refers to a method.

  • type-safe function pointers
  • acts as interface to function
  • allows passing function
  • can also do anonymous functions

Useful for:

  • events
  • call-back methods

To use Delegates

  1. define delegate
  2. write function(s) that match delegate (ie params, return value)
  3. assign a variable delegate to the function
  4. pass / call the function

C# Why Delegates - YouTube

Example

public delegate void DoSomethingDelegate(Object p1, Object p2);

public void DoSomething(Object p1, Object p2) {.... ....}

DoSomethingDelegate f = DoSomething;
f(12,45);

OLD Example

public delegate int DoSomething(object a, object b);

    pass function safely to evaluate, etc.
    func( Function f) { f(...) }
    [
        delegate void delfunc(int x, int y); // param must match the func it encompasses.
        ...
        class Sprite() { 
            public void move(int x, int y);
        }
        Sprite sprite = new Sprite();
        SomeClass cl = new SomeClass();  // assume another class...
        ...
        delfunc moveAll = new delfunc(sprite.move);
        moveAll(3,4);  // move sprite to 3,4
        delegate printSomething = new delegate (c1.print);
        moveAll+= printSomething;  // add another delegate func to moveAll
        moveAll(5,10);  // will perform move(5,10), print(5,10).

        // One can chain as many delegate functions...
        moveAll-=printSomething;  // remove a delegate func from the chain

Func, Action, Predicate

Func<T, TResult>: returns TResult

Func<int,string, bool>: param(int,string), returns bool Example:

Func<int,bool> func = i => i > 5;

Predicate<T>: same as Func<T, bool>

Action<T>: does not return anything, ie returns void

c# - Delegates: Predicate Action Func - Stack Overflow

chain several functions

Delegates are invoked in the order they are added.

moveAll += anotherDelFunc;
moveAll += new moveAll(c1.climb);
moveAll -= anotherDelFunc;   // remove this delegate from chain
moveAll = null; // set to empty 

To pass as a parameter:

void display(moveAll f) { f(5,4); }

Event

Delegate is used to do event-handling.

Event-handler using delegates. By convention, returns void, 2 params.

public delegate void __Handler(SOURCE_OF_EVENT, EventArgs)
    SOURCE_OF_EVENT: publisher of event, ie obj that raises event
    EventARgs: base class for all event data
        contains useful info about this event, such as coordinates, time,

delegate <eventHandler> (object source, System.Eventargs arg);
    arg can be derived to have custom arg.
    [   
        delegate void MoveEventHandler(object source, MoveEventArgs e);

        // from Oreilly's C# Essential
        public class MoveEventArgs : EventArgs {
        public int _newPosition;
        public bool cancel;
        public MoveEventArgs(int newPosition) { // ctor
            _newPosition = newPosition; }
        }
    ]

event is a shortcut to a class that implements delegate func’s +=,-=.

public event <delegateFunc> <eventName>
    add(<event>)
    remove(<event>)

Add events

e += new SomeEventHandler(SomeEvent)

// shortened version
e += SomeEvent

Fire event

public class Slider {
    int _position;
    public event MoveEventHandler Move;
    public int Position {
        get { return _position; }
        set {
            if (position != value) { // if position changed
            if (Move != null) { // if invocation list not empty
                MoveEventArgs args = new MoveEventArgs(value);
                Move(this, args); //--- fire event!!!
                if (args.cancel)
                return;
            }
            position = value;
            }
        }  
    }
}

Finally, in form:

class Form {
    static void Main( ) {
    Slider slider = new Slider( );
    // register with the Move event
    slider.Move += new MoveEventHandler(slider_Move);
            // -----ADD ANOTHER func, see slider_Move() BELOW....
    slider.Position = 20;
    slider.Position = 60;
    }
    // vvv--- THIS GETS added to MoveEventHANDLER()
    static void slider_Move(object source, MoveEventArgs e) {
    if(e.newPosition < 50)
        Console.WriteLine("OK");
    else {
        e.cancel = true;
        Console.WriteLine("Can't go that high!");
    }
    }
}

Anonymous functions using delegate

  • C# 2.0+
  • Should use lambda instead.
  • requires it to be delegate

    delegate (params…) { … code …}

    eventX+= delegate (object obj, EventArgs arg)

    { // do something }

Lambda

  • C# 3.0+
  • Good rule of thumb:

    • 1 or 2 line max
    • longer should use regular function

    eventX+= (obj, arg)=> { … code… }

No parameter:

() =>{...code ...}
() => callMe()

1 parameter, can optionally skip parentheses:

  • ? Does it need return statement?

    n=> {n*n}; (n)=> {n*n}; // unnecessary ( )

1 statement, can optionally skip braces:

  • automatically returns the last statement

    n=> n*n;

2 parameters

(x,y) => x==y
(int x, string s) => s.Length > x

Lambda examples

// [A neat little type inference trick with C#](http://joelabrahamsson.com/a-neat-little-type-inference-trick-with-c/)
var strings = new List<string> {"first", "second"};
strings.Where<string>(x => x.StartsWith("s"));

Anonymous delegate: Lambda in Delegates

// [Lambda Expressions (C# Programming Guide) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions)
delegate void TestDelegate(string s);
TestDelegate del = n => { string s = n + " World"; 
    Console.WriteLine(s); };

delegate int del(int i);  
static void Main(string[] args)  {  
    del myDelegate = x => x * x;  
    int j = myDelegate(5); //j = 25  
}  

Anonymous vs lambda

anonymous function: introduced in c# 2.0.

  • can only be used in context of delegates.

lambda introduced in c# 3.0.

  • works with LINQ

c# - delegate keyword vs. lambda notation - Stack Overflow

C# Anonymous Methods vs. Lambda Expressions - YouTube Lambda

Func<int,bool> func = i => i > 5;
// last param "bool" is the return type
func(3);
func(7);

Anonymous

Func<int,bool> func = delegate(int i) { return i>5;};
func(3);
func(7);