Sie sind auf Seite 1von 3

Delegates and Events: What are They and How are they used.

Abstract
I was made aware of how many programmers are new to C# have a difficult time understanding Delegates. A
delegate is a fundamental concept and is a critical part to events and windows forms.

This tutorial is intended for those new to the C# programming language or for those who are interested in
learning about Delegates. I will focus this tutorial on describing just what Delegates are and how to use them.

Delegates History
The C/C++ languages have what are called function pointers. These are pointers that allow you to access a
function without actually knowing its name. One key fact about these pointers is that they can't point to random
functions. These pointers are specific to a function footprint or functions with the same type and number of
parameters and the same return type. Consider the following qsort code

typedef int (*CMP_FUNC_PTR)(void *, void *);

int sortCmp(void* a, void* b) { ... }

int qsort(void* a, void*b)


{
CMP_FUNC_PTR cmpFunc = sortCmp;

(...)
for (i = left+1; i <= right; i++)
if (cmpFunc(v[i], v[left]) < 0)

(...)
}
In the above example, we created a function pointer in line 1. This pointer must take 2 void* parameters and will
return an integer result. We then typedef this pointer to CMP_FUNC_PTR.We then creates a variable called
cmpFunc and assign it the function sortCmp. We can now use the variable cmpFunv.

As you can see here, there is a lot of power in having a function pointer. In the qsort example, we can change
cmpFunc to point to a variety of different functions depending on our needs.

In C#, we have the similar capabilities through the use of delegates.

How to use Delegates


Delegates are in similar to the C/C++ function pointer. This is how they are declared:
public delegate [return type] [Delegate Name] ( [list of parameters] );

where [return type] is the return type of the function, [Delegate Name] is the name of this delegate, and [List of
parameters] is the list of the parameters in the function you want to point to.

So how are they used. I'll first show a short syntactical example, and then a more realistic example. So the short
version...

public delegate int CMP_FUNC(object x, object y);

public int myCmpFunc(object x, object y) { ... }

public void sort()


{
CMP_Func foo = new CMP_FUNC(myCmpFunc);
...
if (foo(x, y) < 0)
System.Console.WriteLine("Object X is less than Object Y");
else if (foo(x, y) = 0)
System.Console.WriteLine("Object X equals Object Y");
else
System.Console.WriteLine("Object X is greater than Object Y");
}

In the code sample above, we declared a delegate CMP_FUNC to hold a pointer to a function that takes two
objects (x and y) as parameters and returns an int. In the sort function above, we declare a variable foo to
represent our delegate CMP_FUNC. We then instantiate a copy of our delegate CMP_FUNC and tell it to point to
function myCmpFunc. Now instead of calling myCmpFunc directly, you can use the delegate variable foo which
will act like myCmpFunc.

So you maybe wondering why go through all the trouble of using delegates. Consider the following code sample
of an Array Class

class MyArray
{

private object [] myObjects;

public delegate int CMP_FUNC(object x, object y);

void sort(CMP_FUNC cmpFunc)


{
qsort(cmpFunc, 0, 5);
}

private void qsort(CMP_FUNC cmpFunc, int lower, int upper)


{
if (lower >= upper)
return;

object x = myObjects[upper];
int idx = lower - 1;

for (int j = lower; j < upper; j++)


{
if (cmpFunc(myObjects[j], x) <= 0)
{
idx++;
object tmp = myObjects[j];
myObjects[j] = myObjects[i];
myObjects[i] = tmp;
}
}

idx++;
myObject[upper] = myObjects[idx];
myObjects[idx] = x;

qsort(cmpFunc, lower, idx - 1);


qsort(cmpFunc, idx + 1, upper);
}
}
And you want to sort the objects in the array. What are the conditions that you will use to sort Objects? Doesn't
this depend on the object itself? One way to solve this is to write your own object comparison function and have
the sorting routine call this function when comparing to objects (like the qsort function above.)

Delegates do differ from the C/C++ concept of function pointers. Here are some of the differences:

1. Runtime Instantiation vs Static Instantiation: Delegates are dynamic structures and are declared at
runtime. In C/C++ you needed to know the function ahead of time before you can use the function
pointers. In C#, delegates require runtime instantiation. This allows you the opportunity to not only
using static methods but methods in class instances as well.
2. Chaining Delegates don't just point to a single function. Rather they can be thought of as an ordered set
of functions where each function in the set as the same function footprint (same return type and same
number and types of parameters). Consider the following example.

publid delegate void printFuncs (String name);

public void printToScreen(String name) { ... }


public void printToComPort(String name) { ... }
public void printToPrinter(String name) { ... }

public void dbQuery() {


printFuncs print = new printFuncs(printToScreen);
print += new printFuncs(printToComPort);
print += new printFuncs(printToPrinter);

print("DotNetExtreme");
}
In this example, when you execute the delegate variable print it will in turn call printToScreen, printToComPort,
and printToPrinter. NOTE: The order in which you add these functions is important. In the print example above,
when delegate variable print is execute, printToScreen will be called first, then printToComPort, then
printToPrinter. The functions will not be called in any other order. Also note that if any function in the chain
throws an exception, the rest of the chain will not be executed.

Das könnte Ihnen auch gefallen