Delegates
A delegate is defined using the delegate
keyword. The declaration looks like a function signature, but the compiler actually introduces a class that can hold references to methods whose signatures match the signature of the delegate. A delegate can hold references to either static or instance methods.
public enum Status { Started, Stopped }
public delegate void StatusChange(Status status);
public class Engine
{
private StatusChange statusChangeHandler;// is Delegate return true
public void RegisterStatusChangeHandler(StatusChange handler)
{
statusChangeHandler = handler;
}
public void Start()
{
// start the engine
if (statusChangeHandler != null)
statusChangeHandler(Status.Started);
}
public void Stop()
{
// stop the engine
if (statusChangeHandler != null)
statusChangeHandler(Status.Stopped);
}
}
Combining delegates
Expression | Result |
---|---|
null + d1 | d1 |
d1 + null | d1 |
d1 + d2 | [d1, d2] |
d1 + [d2, d3] | [d1, d2, d3] |
[d1, d2] + [d2, d3] | [d1, d2, d2, d3] |
[d1, d2] – d1 | d2 |
[d1, d2] – d2 | d1 |
[d1, d2, d1] – d1 | [d1, d2] |
[d1, d2, d3] – [d1, d2] | d3 |
[d1, d2, d3] – [d2, d1] | [d1, d2, d3] |
[d1, d2, d3, d1, d2] – [d1, d2] | [d1, d2, d3] |
[d1, d2] – [d1, d2] | null |
Events
Events aren’t Delegate instances.
using System;
class Test
{
public event EventHandler MyEvent
{
add
{
Console.WriteLine ("add operation");
}
remove
{
Console.WriteLine ("remove operation");
}
}
static void Main()
{
Test t = new Test();
t.MyEvent += new EventHandler (t.DoNothing);
t.MyEvent -= null;
}
void DoNothing (object sender, EventArgs e)
{
}
}
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
Lambda expressions
- The variables that are introduced in a lambda expression are not visible outside the lambda (for instance, in the enclosing method).
- A lambda cannot capture
in
,ref
, orout
parameters from the enclosing method. - Variables that are captured by a lambda expression are not garbage collected, even if they would otherwise go out of scope until the delegate that the lambda is assigned to is garbage collected.
bool IsOdd(int n) { return n % 2 == 1; }
var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list.RemoveAll(IsOdd);
var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list.RemoveAll(delegate (int n) { return n % 2 == 1; });
var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list.RemoveAll(n => n % 2 == 1);