The goals of this articles is to present very short (as possible) an overview about delegates and events
The "hot" shots of this article are :
What is a delegate ? A delegate is an object who report a method.When we create a delegate, we actually create an object who will memorize a reference to a method.This method can appeal through this reference.Even if a method is not an object, this method will have a physical location inside of the memory.
The Delegate class is the base class for delegate types. However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class. It is also not permissible to derive a new type from a delegate type. The Delegate class is not considered a delegate type; it is a class used to derive delegate types.
Most languages implement a delegate keyword, and compilers for those languages are able to derive from the MulticastDelegate class; therefore, users should use the delegate keyword provided by the language.
The declaration of a delegate type establishes a contract that specifies the signature of one or more methods. A delegate is an instance of a delegate type that has references to:
An instance method of a type and a target object assignable to that type.
An instance method of a type, with the hidden this parameter exposed in the formal parameter list. The delegate is said to be an open instance delegate.
A static method.
A static method and a target object assignable to the first parameter of the method. The delegate is said to be closed over its first argument.
Now let's see an simple example of delegates :
//** simple example of delegates using System; //** declaring a delegate delegate string strMod(string str); class DelegateTest { //** we replace spaces with lines static string replaceSpaces(string a) { Console.WriteLine("Replace spaces with lines."); return a.Replace(' ', '-'); } //** delete spaces static string removeSpaces(string a) { string temp = ""; int i; Console.WriteLine("Delete spaces."); for (i = 0; i < a.Length; i++) if (a[i] != ' ') temp += a[i]; return temp; } //** string reverse static string reverse(string a) { string temp = ""; int i, j; Console.WriteLine("Reverse string."); for(j = 0; i = a.Length - 1; i >=0; i--; j++) temp += a[i]; return temp; } public static void Main() { //** Building delegates strMod strOp = new strMod(replaceSpaces); string str; //** calling methods using delegates str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); Console.WriteLine(); strOp = new strMod(removeSpaces); str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); Console.WriteLine(); strOp = new strMod(reverse); str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); } }
The result of this code will be :
Replace spaces with lines. The result string is : This-is-a-test Delete spaces. The result string is : Thisisatest Reverse string. The result string is : tsest a si siht
Now let's study toghether a little the code to understand much better how the things are going :
strMod strOp = new strMod(replaceSpaces);
str = strOp("This is a test.");
Because strOp refer replaceSpaces() method, this will the invoked method.Then to strOp will be added an reference to removeSpaces method, after, strOp delegates is called one more time.This time the invoked method will be removeSpaces().Final to strOp will add a reference to reverse(), after the delegate is called .This will establish a call of reverse() method.
In the next example, is the same example like above one, the single difference is that the operations over the strings are encapsulated into a class named StringOps :
//** delegates can refer instance method using System; //** declaring an delegate delegate string strMod(string str); class StringOps { //** replace spaces with lines public string replaceSpaces(string a) { Console.WriteLine("Replace spaces with lines."); return a.Length(' ', '-'); } //** deleting spaces public string removeSpaces(string a) { string temp = ""; int i, j; Console.WriteLine("Deleting spaces."); for(i = 0; i < a.Length; i++) if(a[i] != ' ') temp += a[i]; } //** reverse the string public string reverse(string a) { string temp = ""; int i, j; Console.WriteLine("Reverse the string."); for(j = 0, i = a.Length - 1; i >= 0; i--, j++) temp += a[i]; return temp; } class DelegateTest { public static void Main() { StringOps so = new StringOps(); //** building delegates strMod strOp = new strMod(so.replaceSpaces); string str; //** calling methods using delegates str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); Console.WriteLine(); strOp = new strMod(removeSpaces); str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); Console.WriteLine(); strOp = new strMod(reverse); str = strOp("This is a test."); Console.WriteLine("The result string is : " + str); } } }
This program produced the same result like the first one, but in this case delegates refer methods using an instance of class StrOps.
One of the most interesting facilities that delegates offer is the ability of multicasting.t times, it is desirable to call two (or more) implementing methods through a single
delegate. This becomes particularly important when handling events (discussed later
in this chapter).
The goal is to have a single delegate that invokes more than one
method. For example, when a button is pressed, you might want to take
more than one action.Two delegates can be combined with the addition operator (+). The result is a new multicast delegate that invokes both of the original implementing methods.
In simple terms, the multicasting term designate the ability to create a methods chain who will be automatically called when the delegate will be invoked.A chain like this is very simple to create.Is enough to create an instance of a delagate and then using the += operator we can add methods in chain.To delete or eliminate a method from chain you have to use -=.
Nota bene !!! Also we can use the +, - and = , independent to add and decrease delegates, but += and -= are more used.The single restriction is that the multicast delegates has to return a result of void type.
Down, we have an example of multicastin.This restriction rewrite the two examples above, the single modification is the return type by the methods with strings at void and using a ref parameter to return the modified string in the module that has been called.
//** Present the multicasting term using System; //** delegate declaring delegate void strMod(ref string str); class StringOps { //** we replace spaces with lines static string replaceSpaces(ref string a) { Console.WriteLine("Replace spaces with line."); Console.WriteLine(' ', '-'); return a.Replace(' ', '-'); } //** delete spaces static string removeSpaces(ref string a) { string temp = ""; int i; Console.WriteLine("Delete spaces."); for (i = 0; i < a.Length; i++) if (a[i] != ' ') temp += a[i]; return temp; a = temp; } //** string reverse static string reverse(ref string a) { string temp = ""; int i, j; Console.WriteLine("Reverse string."); for(j = 0; i = a.Length - 1; i >=0; i--; j++) temp += a[i]; return temp; a = temp; } public static void Main() { //** building delegates strMod strOp; strMod replaceSp = new strMod(replaceSpaces); strMod removeSp = new strMod(removeSpaces); strMod reverseStr = new strMod(reverse); string str = "This is a test"; //** creatin a multicast delegate strOp += replaceSp; strOp += reverseStr; //** multicast delegate call strOp(ref str); Console.WriteLine("The result string is : " + str); Console.WriteLine(); //** remove replacing with lines and add deleting of spaces strOp -= replaceSp; strOp += removeSp; str = "This is a test"; //** reinitialize the string //** multicast delegate call strOp(ref str); Console.WriteLine("The result string is : " + str) Console.WriteLine(); } }
This program will show on screen the following messages :
Replace spaces with line. Reverse the string. The result string is : tsest a si sihT Reverse the string. Delete spaces. The result string is : tsestasisihT.
Let's examine a little the code without going to deep in it.We can see that in the Main() method , are created four instances having delegate type.The next three delegates refer each a specific method who modify the characters string.After that a multicast delegate is created who call removeSpaces() and reverse() methods.This is made in the next line :
strOp = replaceSp; strOp += reverseStr;
First, to strOp we appeal an reference to replaceSp. Using after the += operator, we add also the reverseStr delegate.When strOp is invoked , both methods will be called, replacing spaces with lines and reversing the string.
Forward, the delegate is eliminated from the chain, using the next line
strOp -= replaceSp;
after we add removeSp, using the line
strOp += removeSp;
We invoked one more time the strOp delegate.This time the string will be reversed and the spaces will be deleted.
Event is another facility of C# language that is very important.An event show when an action take place.The events are members entity of a class.The general form of declaration is :
event event-delegate object-name;
Let's explain a bit the general form : event-delegate represent the name of the delegate that is used for event treatment and object-name is the name of the event instance that is created.Let's start by showing a simple example :
//** A simple case of using events using System; //** declare an delegate for an event delegate void MyEventHandler(); //** declare an event class class MyEvent { //** declare the event public event MyEventHandler activate; //** the method that is called on event loading public void fire() { if (activate != NULL) activate(); //** loading the event } } class EventDemo { static void handler() { Console.WriteLine("The event has been made."); } public static void Main() { MyEvent evt = new MyEvent(); //** create the instance on an event //** add the routine of treatment in chain evt.activate += new MyEventHandler(handler); evt.fire(); //** generating of an event } }
This program will show :
The even has been made.
The next example will show an multicast event.
The events can be multicas.This allows many objects to respond to an event notice.Down we have an example of multicast event.
//** A simple case of using an multicast event using System; //** declare an delegate for an event delegate void MyEventHandler(); //** declare an event class class MyEvent { //** declare the event public event MyEventHandler activate; //** the method that is called on event loading public void fire() { if (activate != NULL) activate(); //** loading the event } } class X { public void Xhandler() { Console.WriteLine("Event received by an X object"); } } class Y { public void Yhandler() { Console.WriteLine("Event received by an Y object"); } } class EventDemo { static void handler() { Console.WriteLine("Event received by EventDemo"); } public static void Main() { MyEvent evt = new MyEvent(); //** create the instance on an event X xOb = new X(); Y yOb = new Y(); //** we add the treatment routines to the event list evt.activate += new MyEventHandler(handler); evt.activate += new MyEventHandler(xOb.Xhandler); evt.activate += new MyEventHandler(yOb.Yhandler); evt.fire(); //** generating of an event Console.WriteLine(); //** delete a treatment routine evt.activate -= new MyEventHandler(xOb.Xhandler); evt.fire(); } }
The program will show :
Event received by EventDemo Event received by an X object Event received by an Y object Event received EventDemo Event received an Y object.
The next program will show you how to distribute an event to three instances having X type.The code is :
//** Events are fated to instances not classes using System; //** declare an delegate for an event delegate void MyEventHandler(); //** declare an event class class MyEvent { //** declare the event public event MyEventHandler activate; //** the method that is called on event loading public void fire() { if (activate != NULL) activate(); //** loading the event } } class X { int id; public X(int x) { id = x; } public void Xhandler() { Console.WriteLine("An event received by an instance " + str); } } class EventDemo { public static void Main() { MyEvent evt = new MyEvent(); //** create the instance on an event X o1 = new X(1); X o2 = new X(2); X o3 = new X(3); //** we add the treatment routines to the event list evt.activate += new MyEventHandler(o1.Xhandler); evt.activate += new MyEventHandler(o2.Xhandler); evt.activate += new MyEventHandler(o3.Xhandler); evt.fire(); //** generating of an event } }
This program will show :
An event received by instance 1 An event received by instance 2 An event received by instance 3
I will add to this articles, namespaces and how to use them toghether with delegates and events.
I hope this article has make a clear view and will be like a small guide through delegates and events.
HAPPY CODING !!!!!
| You must Sign In to use this message board. | |||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||