method returns the summation of the integer value passed as an argument. The
method returns a string that is the reverse of the string passed as an argument.
PART I
C h a p t e r 1 8 :
G e n e r i c s
529
PART IPART I
In similar fashion, the delegate
strDel
is created and assigned a reference to
Reflect( )
:
SomeOp strDel = Reflect;
Because
Reflect( )
takes a
string
argument and returns a
string
result, it is compatible with
the string version of
SomeOp
.
Because of the type safety inherent in generics, you cannot assign incompatible methods
to delegates. For example, assuming the preceding program, the following statement would
be in error:
SomeOp intDel = Reflect; // Error!
Because
Reflect( )
takes a
string
argument and returns a
string
result, it cannot be assigned
to an
int
version of
SomeOp
.
As explained in Chapter 15, one of the major uses of delegates occurs when handling
events. Although events, themselves, cannot be generic, the delegate that supports an event
can. The following program reworks an example from Chapter 15 (the .NET-compatible
event demonstration) so that it uses a generic delegate:
// Convert event example from Chapter 15 to use generic delegate.
using System;
// Derive a class from EventArgs.
class MyEventArgs : EventArgs {
public int EventNum;
}
// Declare a generic delegate for an event.
delegate void MyEventHandler
(T source, V args);
// Declare an event class.
class MyEvent {
static int count = 0;
public event MyEventHandler SomeEvent;
// This fires SomeEvent.
public void OnSomeEvent() {
MyEventArgs arg = new MyEventArgs();
if(SomeEvent != null) {
arg.EventNum = count++;
SomeEvent(this, arg);
}
}
}
class X {
public void Handler(T source, V arg) where V : MyEventArgs {
Console.WriteLine("Event " + arg.EventNum +
" received by an X object.");
www.freepdf-books.com
530
P a r t I :
T h e C # L a n g u a g e
Console.WriteLine("Source is " + source);
Console.WriteLine();
}
}
class Y {
public void Handler(T source, V arg) where V : MyEventArgs {
Console.WriteLine("Event " + arg.EventNum +
" received by a Y object.");
Console.WriteLine("Source is " + source);
Console.WriteLine();
}
}
class UseGenericEventDelegate {
static void Main() {
X ob1 = new X();
Y ob2 = new Y();
MyEvent evt = new MyEvent();
// Add Handler() to the event list.
evt.SomeEvent += ob1.Handler;
evt.SomeEvent += ob2.Handler;
// Fire the event.
evt.OnSomeEvent();
evt.OnSomeEvent();
}
}
The output is show here:
Event 0 received by an X object.
Source is MyEvent
Event 0 received by a Y object.
Source is MyEvent
Event 1 received by an X object.
Source is MyEvent
Event 1 received by a Y object.
Source is MyEvent
Generic Interfaces
In addition to generic classes and methods, you can also have generic interfaces. Generic
interfaces are specified just like generic classes. Here is an example that reworks the
ISeries
interface developed in Chapter 12. (Recall that
ISeries
defines the interface to a class that
generates a series of numbers.) The data type upon which it operates is now specified by
a type parameter.
www.freepdf-books.com