Apr 10, 2007

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

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

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

delegate (params...) { ... code ...}

eventX+= delegate (object obj, EventArgs arg)
    { // do something }

Lambda

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

No parameter:

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

1 parameter, can optionally skip parentheses:

n=> {n*n};

1 statement, can optionally skip braces:

n=> n*n;

Anonymous vs lambda

anonymous function: introduced in c# 2.0.

lambda introduced in c# 3.0.