Hi Author--I'm not really qualified to answer completely, as I'm still
learning, but here's my two cents.
I have been closely following this thread these days. Is it the case
that at the end of the day, delegate is only useful in event handling?
Yes, this seems to be the case. Also if you do a "publisher -
subscriber" model, where you can fire the publisher at one part of
your class, and all subscribers that are listening will respond in the
rest of your code, kind of like a global, multicast "GOTO" (in my
mind's eye). But, you can also do the same thing simply by
judiciously calling other 'subscribing' methods from inside the method
that is 'publishing', and achieve the same thing, so to a degree it's
syntatic sugar or eye candy. Actually I find it more confusing, but
maybe because I'm still new to the delegates thing. Getting the hang
of it though.
I experimented with multicast delegate with the following code, but
got an exception which says: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
I had no problems compiling and running this code. To speed up the
program, I commented out the part where you have to hit a key, //
Console.ReadKey, and got this output, as expected:
M1: Just a test.
M2: Just a test.
Press any key to continue . . .
To see that M2 is being executed you can switch the order of +s1 and
+s2, to get "M2: a test. Just", as you would expect.
The code itself seems to be OK. What does this exception really
mean?
Nothing. I think you have a hardware problem. Check you physical
memory with one of these memory stress test programs you can get free
on the web.
BTW, I don't understand how useful multicast delegate can be. It
seems to me that its only purpose is to "simplify" calling multiple
methods with one call. But all methods have to have the same
signature and all of them have to be registered with the given
multicast delegate. Plus, how often does it happen that multiple
methods have the same signature, return void, and need to be called
one after another? Maybe there are such typical situations in
software development which I don't know?
Well, the .NET framework uses these all the time. Seems C#
programmers like to even make your 'custom' method inhereit
from :EventArgs, so you might have a custom class--
public class MyCustomClass: EventArgs
{
// stuff here
}
Then, in another class in the same 'scope' / namespace,
pubic class SecondClass
{
public event EventHandler <MyCustomClass> MyEventHandler; //note
MyCustomClass is a derived class from EventHandler, so this is OK
//and, my book says the 'convention' is to write a protected virtual
method that fires this event, prefixed with the word 'On', and then
accept a single EventArgs argument like so:
protected virtual void OnMyEventHandler (MyCustomClass e) // 'e' is
conventionally used to designate a class that's of type EventArgs
{
if (MyEventHandler != null) //always check to see eventhandler is not
null, or exception thrown
{ MyEventHandler(this, e);}
//
}
//then you have a method with signature "object, EventArgs" like so,
somewhere in one of your classes within the same namespace scope:
static void AMethodHere (object sender, MyCustomClass e)
{
// do stuff with 'e', which carries the information, while object
sender is almost always, from the examples I've seen, the 'this'
reference
}
To fire this Event, you use this convention:
SecondClass.MyEventHandler += AMethodHere; // this is known as
"registration", and you can also use this older format:
SecondClass.MyEventHandler += new EventHandler(AMethodHere);
//then, you 'fire' after registration like this:
MyCustomClass myCustomClass1 = new MyCustomClass;
MyEventHandler(this,myCustomClass1); //usually this is called inside
another class, hence 'this' //this is the firing
or, you can use the "On" method above like so;
OnMyEventHandler(myCustomClass); //which fires it the same way, but
checks first for null pointer
Sorry if this was confusing, you just have to see a lot of examples
before you get it. The format changes slightly but the underlying
stuff is largely the same.
RL