Delegates
A delegate dynamically wires up a
method caller to its target method. There are two aspects to a delegate: type
and instance. A delegate type defines a protocol to which the caller and target
will conform, comprising a list of parameter types and a return type. A
delegate instance is an object that refers to one (or more) target methods
conforming to that protocol.
A
delegate instance literally acts as a delegate for the caller: the caller
invokes the delegate, and then the delegate calls the target method. This
indirection decouples the caller from the target method.
A
delegate type declaration is preceded by the keyword delegate, but otherwise it
resembles an (abstract) method declaration.
delegate int Transformer (int x);
To
create a delegate instance, you can assign a method to a delegate variable:
public class Test
{
static void
Main()
{
Transformer t = Square; // Create delegate instance
int result = t(3); // Invoke delegate
Console.WriteLine (result); // 9
}
static int
Square (int x) { return
x * x; }
}
Invoking a delegate is just like
invoking a method (since the delegate's purpose is merely to provide a level of
indirection) :
t(3);
The statement:
Transformer t = Square;
is shorthand for:
Transformer t = new Transformer(Square);
and:
t(3);
is shorthand for:
t.Invoke (3);
Multicast Delegates
All delegate instances have multicast
capability. This means that a delegate instance can reference not just a
single target method, but also a list of target methods. The + and += operators
combine delegate instances. For example:
SomeDelegate d = SomeMethod1;
d += SomeMethod2;
The last line is functionally the same
as:
d = d + SomeMethod2;
Invoking d will now call both SomeMethod1
and SomeMethod2. Delegates are invoked
in the order they are added.
The - and -= operators remove the
right delegate operand from the left delegate
operand. For example:
d -= SomeMethod1;
Invoking d will now cause only SomeMethod2
to be invoked.
Calling + or += on a delegate variable
with a null value works, and it is equivalent to assigning the variable to a
new value:
SomeDelegate d = null;
d += SomeMethod1; // Equivalent (when
d is null) to d = SomeMethod1;
Similarly, calling -= on a delegate
variable with a single target is equivalent to assigning
null to that variable.
If a multicast delegate has a nonvoid
return type, the caller receives the return value from the last method to be
invoked .