Delegates and Events

M

mick

The next part of C# I`m trying to get my head around is Events. I`m a bit
confused why in some examples it says you declare an Event thus:

public event EventHandler MyEvent

and some have a delegate as well:

public delegate void EventHandler(Object sender, EventArgs e)
public event EventHandler MyEvent.

If the first one works (and it does) why use the second. Clearly I`m
missing something. Can someone give me a nudge in the right drection.

TIA,

mick
 
H

Harlan Messinger

mick said:
The next part of C# I`m trying to get my head around is Events. I`m a bit
confused why in some examples it says you declare an Event thus:

public event EventHandler MyEvent

and some have a delegate as well:

public delegate void EventHandler(Object sender, EventArgs e)
public event EventHandler MyEvent.

If the first one works (and it does) why use the second. Clearly I`m
missing something. Can someone give me a nudge in the right drection.

System.EventHandler *is* a delegate, one that's predefined in the manner
you showed above. You wouldn't define it again in your own code. I don't
know where you're seeing it, but it's probably being shown just to
clarify what "EventHandler" signifies and to give you an example for
creating your own Event handlers. You would do that if your custom event
needs a handler that takes as arguments something other than the one
Object, one EventArgs combination.
 
M

mick

Harlan Messinger said:
System.EventHandler *is* a delegate,

Yes, this is how I understood it. However ve been reading through this
article
http://www.codeproject.com/KB/cs/event_fundamentals.aspx
and at part 6.3 it says

"It should be clearly understood that events are not delegates � even though
events are very much dependent upon delegates, and in some ways can be seen
as a form of a delegate implementation. Events are also not delegate
instances, even if they can be used in very similar ways."

Is he wrong?
one that's predefined in the manner you showed above. You wouldn't define
it again in your own code. I don't know where you're seeing it, but it's
probably being shown just to clarify what "EventHandler" signifies and to
give you an example for creating your own Event handlers. You would do
that if your custom event needs a handler that takes as arguments
something other than the one Object, one EventArgs combination.

That clears it up nicely. Thanks for that.

mick
 
P

Peter Duniho

mick said:
The next part of C# I`m trying to get my head around is Events. I`m a bit
confused why in some examples it says you declare an Event thus:

public event EventHandler MyEvent

and some have a delegate as well:

public delegate void EventHandler(Object sender, EventArgs e)
public event EventHandler MyEvent.

As EventHandler is already defined in .NET, you should never see the
above. But you very well could see other examples where a delegate type
not already found in .NET is declared and used for the event.
If the first one works (and it does) why use the second. Clearly I`m
missing something. Can someone give me a nudge in the right drection.

You can do either. IMHO, it is often useful to follow the .NET pattern.
Note that there's now a generic EventHandler<T> delegate type that you
can use. It used to be you had to declare both an EventArgs subclass
and then a delegate type to go with it. Now you can just do the former,
and use the generic delegate type:

class MyEventArgs : EventArgs
{
public string Data { get; set; }

public MyEventArgs(string str)
{
Data = str;
}
}

class MyClass
{
public EventHandler<MyEventArgs> MyEvent = delegate { };

public void Method()
{
// do some stuff

// ...then raise the event:
MyEvent(this, new MyEventArgs("Hello"));
}
}

class MyOtherClass
{
public void OtherMethod()
{
MyClass mc = new MyClass();

mc.MyEvent += (sender, e) =>
{
Console.WriteLine("event string: " + e.Data);
}

mc.Method();
}
}

By the way, you may notice that I initialize the event with " = delegate
{ }". This is not mandatory, but it simplifies the code elsewhere by
avoiding the need to check the event field for null before invoking it,
since you know the event will always contain at least that one
degenerate handler.

There is a slight memory and performance overhead to the technique, but
it does make the code examples a lot simpler to write and to read. :)
In most applications, the extra run-time overhead isn't an issue at all.

Pete
 
H

Harlan Messinger

mick said:
Yes, this is how I understood it. However ve been reading through this
article
http://www.codeproject.com/KB/cs/event_fundamentals.aspx
and at part 6.3 it says

"It should be clearly understood that events are not delegates � even
though events are very much dependent upon delegates, and in some ways
can be seen as a form of a delegate implementation. Events are also not
delegate instances, even if they can be used in very similar ways."

Is he wrong?

He's absolutely correct, and he doesn't contradict what I said.
EventHandler is a delegate, not an Event. The only Event you mentioned
in your original post was the one called MyEvent. The declaration of
MyEvent, above, says that the MyEvent event calls for handlers that can
be wrapped in delegates of the EventHandler variety.
 
P

Peter Duniho

mick said:
Yes, this is how I understood it. However ve been reading through this
article
http://www.codeproject.com/KB/cs/event_fundamentals.aspx
and at part 6.3 it says

"It should be clearly understood that events are not delegates � even
though events are very much dependent upon delegates, and in some ways
can be seen as a form of a delegate implementation. Events are also not
delegate instances, even if they can be used in very similar ways."

Is he wrong?

No, but neither does he contradict what Harlan wrote. The type
"System.EventHandler" isn't an event, it's a delegate type.

An event, on the other hand, requires a delegate type. But an event
isn't a delegate type or a delegate per se. It just _uses_ a delegate type.

An event is an encapsulation, similar to a property. In the case of the
event, it encapsulates an "add" and a "remove" method. Each method
takes as the single parameter an instance of a delegate. The semantics
expected by convention are that calling the "add" method will add the
passed in delegate to some list of delegates to invoke when the event is
raised, while the "remove" method will of course remove the passed in
delegate from that same list.

Of course, if you implement the event explicitly (you usually see
"automatic" events, which are like automatic properties in that the
compiler generates the implementation for you, but you can provide the
"add" and "remove" methods yourself, just as you can provide "get" and
"set" methods for properties), you can do whatever you like with the
delegate reference passed to your "add" and "remove" methods. But if
you don't follow the expected conventions, you'll have a seriously
confused program. :)

And of course, with all that in mind, you can see that when you write
code like this:

obj.MyEvent += SomeEventHandlerMethod;

....the compiler is simply automatically creating a delegate instance for
you (e.g. generating an expression like "new
EventHandler(SomeEventHandlerMethod)"), and then calling the "add"
method for the "MyEvent" event, passing the delegate reference to the
method.

In fact, you can see how important events were to the C# designers.
They really want you to use them when they make sense, and they've
included all sorts of short-hand syntax to make it easier to do so.

Pete
 
M

mick

Peter Duniho said:
As EventHandler is already defined in .NET, you should never see the
above. But you very well could see other examples where a delegate type
not already found in .NET is declared and used for the event.


You can do either. IMHO, it is often useful to follow the .NET pattern.
Note that there's now a generic EventHandler<T> delegate type that you can
use. It used to be you had to declare both an EventArgs subclass and then
a delegate type to go with it. Now you can just do the former, and use
the generic delegate type:

I was just up to the EventArgs part late last night when I was reading up. I
also
noticed the generics stuff which I just scanned over before I finished.
I`ll look into it in more detail today then write a little test App to see
if I
can put it all together:)
class MyEventArgs : EventArgs
{
public string Data { get; set; }

public MyEventArgs(string str)
{
Data = str;
}
}

class MyClass
{
public EventHandler<MyEventArgs> MyEvent = delegate { };

public void Method()
{
// do some stuff

// ...then raise the event:
MyEvent(this, new MyEventArgs("Hello"));
}
}

class MyOtherClass
{
public void OtherMethod()
{
MyClass mc = new MyClass();

mc.MyEvent += (sender, e) =>
{
Console.WriteLine("event string: " + e.Data);
}

mc.Method();
}
}

By the way, you may notice that I initialize the event with " = delegate
{ }". This is not mandatory, but it simplifies the code elsewhere by
avoiding the need to check the event field for null before invoking it,
since you know the event will always contain at least that one degenerate
handler.

Never seen that used before.
There is a slight memory and performance overhead to the technique, but it
does make the code examples a lot simpler to write and to read. :) In
most applications, the extra run-time overhead isn't an issue at all.

I dont think I`m knowlegeable enough (int this area at least) to have
anything I
would deign to call a "technique", still trying to get the fundamentals in
my head:) All good stuff Pete, thanks for your effort. Really appreciate
it.

mick
 
M

mick

Peter Duniho said:
No, but neither does he contradict what Harlan wrote. The type
"System.EventHandler" isn't an event, it's a delegate type.

An event, on the other hand, requires a delegate type. But an event isn't
a delegate type or a delegate per se. It just _uses_ a delegate type.

An event is an encapsulation, similar to a property. In the case of the
event, it encapsulates an "add" and a "remove" method. Each method takes
as the single parameter an instance of a delegate. The semantics expected
by convention are that calling the "add" method will add the passed in
delegate to some list of delegates to invoke when the event is raised,
while the "remove" method will of course remove the passed in delegate
from that same list.

Of course, if you implement the event explicitly (you usually see
"automatic" events, which are like automatic properties in that the
compiler generates the implementation for you, but you can provide the
"add" and "remove" methods yourself, just as you can provide "get" and
"set" methods for properties), you can do whatever you like with the
delegate reference passed to your "add" and "remove" methods. But if you
don't follow the expected conventions, you'll have a seriously confused
program. :)

And of course, with all that in mind, you can see that when you write code
like this:

obj.MyEvent += SomeEventHandlerMethod;

...the compiler is simply automatically creating a delegate instance for
you (e.g. generating an expression like "new
EventHandler(SomeEventHandlerMethod)"), and then calling the "add" method
for the "MyEvent" event, passing the delegate reference to the method.

In fact, you can see how important events were to the C# designers. They
really want you to use them when they make sense, and they've included all
sorts of short-hand syntax to make it easier to do so.

Hehe. Heads spinning. I think I`m getting muddled between Event and
EventHandler. So to try to get it straight in my mind, does this line of
code

public event EventHandler MyEvent

actually create two things: a delegate (EventHandler) and an Event
(MyEvent)?

mick
 
P

Peter Duniho

mick said:
Hehe. Heads spinning. I think I`m getting muddled between Event and
EventHandler. So to try to get it straight in my mind, does this line of
code

public event EventHandler MyEvent

actually create two things: a delegate (EventHandler) and an Event
(MyEvent)?

Nope. The EventHandler type is already declared elsewhere. Only the
event itself is declared by the line of code above.

Note also that there's a difference between a "delegate" and a "delegate
type". The EventHandler type is a "delegate type". An _instance_ of
that type is an actual "delegate".

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top