14.1 What are delegates?


Think of a delegate as a special type something like a class. [2] A delegate type is a class type that is derived from System.Delegate . When you declare a delegate using the delegate keyword, you do not have to specify that you are deriving from System.Delegate ; that is implicit.

[2] A note for C++ developers: C# delegates are similar to C++ function pointers. However, unlike function pointers, delegates are object-oriented.

A delegate type's main job is to encapsulate one or more methods (see Figure 14.1). A delegate instance is an instance of a delegate type. You can view delegate instances as representations of methods , so that when you invoke a delegate instance, the method(s) it encapsulates is also invoked. [3]

[3] Hence the name 'delegate'.

Figure 14.1. A delegate instance has an invocation list which contains one or more methods. When the delegate instance is invoked, the method in its invocation list is invoked.

graphics/14fig01.jpg

All delegate types are implicitly sealed [4] (which means that you cannot derive a subdelegate from any delegate). System.Delegate is also special in the sense that you cannot subclass it into any other class except a delegate. System.Delegate is itself not a delegate, but the superclass of all delegate types. See Figure 14.2.

[4] A sealed class in C# is what is called a final class in Java. See section 6.7.

Figure 14.2. All delegate types are subclasses of System.Delegate .

graphics/14fig02.gif

Like other types, you perform the following steps to use a delegate:

  • declaration of the delegate type;

  • instantiation of a delegate type to create a delegate instance;

  • invocation of a delegate instance.

14.1.1 Declaration

You need to declare a delegate type before you can use it. The syntax for this looks like a method signature:

 [accessibility_modifier] delegate return_type delegate_identifier (parameter list); 

Here is an example:

 public delegate int MyDelegate (string s, int i); 

The statement above declares a delegate type called MyDelegate with public accessibility. MyDelegate returns an int , and takes in two parameters: a string and an int .

Unlike a class type, a delegate type declaration does not start and end with curly braces. You can declare a delegate type within another type (inside another class, or inside an interface), or outside any classes. [5]

[5] The location of declaration, together with its accessibility modifier, will affect the delegate's accessibility. OO common sense still applies concerning accessibility issues for delegates.

I mentioned just now that a delegate instance is used to encapsulate one method. Only methods with:

  • the same return type,

  • the same number of parameters,

  • the same parameter types, in the same order,

as the delegate type declaration can be represented by a delegate instance of this delegate type.

In this case, methods that can be encapsulated by an instance of the MyDelegate delegate type must:

  • return an int AND

  • take in a string and an int as parameters (in that order).

Examples of methods which are compatible with MyDelegate are:

  • private int MyMethod1 (string a, int b){...}

  • public static int MyMethod2 (string a_string, int an_int){...}

14.1.2 Instantiation

Each delegate instance maintains an invocation list internally. This list contains the ordered list of methods the delegate instance represents. I shall discuss inserting more than one method into the invocation list in section 14.3. For now, just assume that each delegate instance has only one method in its invocation list.

Like classes, you create an instance of a delegate using the new keyword. The delegate type constructor takes in either a method reference or another delegate instance.

A newly created delegate instance can refer to any of:

  • a static method;

  • an instance method (in which case, both the class instance and its method are encapsulated);

  • another delegate.

Assuming that MyClass is a user -defined class which contains a static method called MyStaticMethod and a non-static method called MyMethod1 , and mc is an instance of MyClass , here is an example of how to create instances of the MyDelegate type:

 MyDelegate d1 = new MyDelegate(MyClass.MyStaticMethod); 

In this statement, a delegate instance d1 is created. d1 encapsulates a static method of MyClass called MyStaticMethod .

Let's consider another statement:

 MyDelegate d2 = new MyDelegate(mc.MyMethod1); 

In this statement, a delegate instance d2 is created which encapsulates an instance method of a particular instance of MyClass called MyMethod1 .

Both MyStaticMethod and MyMethod1 must have compatible return types (in this case, an int ) and method parameters (a string and an int , in that order) as the MyDelegate delegate type.

14.1.3 Invocation

Invoking a delegate instance simply results in the invocation of the method it represents - or methods, if there is more than one in the delegate instance's invocation list.

Hence, invoking a delegate instance is similar to invocating the method. The parameters passed into the delegate invocation statement are in turn passed into the method as method parameters by the delegate instance.

The following statement invokes the delegate instance d1 , created previously with a string and an int :

 d1("test string", 99); 

This will cause the static method MyClass.MyStaticMethod to be invoked with the same parameters.

Hence, since d1 is a delegate instance that encapsulates the static method MyClass.MyStaticMethod , the two statements below produce the same effect:

 d1("test string", 99); MyClass.MyStaticMethod("test string", 99); 

And also, since d2 is a delegate instance that encapsulates the instance method MyMethod1 of mc , the two statements below produce the same effect:

 d2("hello", 123); mc.MyMethod1("hello", 123); 


From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net