Where is the delegate?

G

Guest

Hello,
Very simple question but one I need clarified.

Which part of the statement below is considered the 'delegate'?

Is it the 'new System.EventHandler'
or the
btnAccept_Click?
or is it the piece of code which doesn't appear here, but abstracts the
btnAccept_Click method?

this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click);

Many thanks for any answers to this semingly silly question.
Ant
 
M

Michael C

Ant said:
Hello,
Very simple question but one I need clarified.

Which part of the statement below is considered the 'delegate'?

Is it the 'new System.EventHandler'
or the
btnAccept_Click?
or is it the piece of code which doesn't appear here, but abstracts the
btnAccept_Click method?

this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click);

btnAccept_Click is the target for the delegate
and "new System.EventHandler" creates an instance of the System.EventHandler
delegate.
this.btnAccept.Click holds none, one or more instances of the
System.EventHandler delegate.

Michael
 
N

Nick Hounsome

Ant said:
Hello,
Very simple question but one I need clarified.

Which part of the statement below is considered the 'delegate'?

Is it the 'new System.EventHandler'
or the
btnAccept_Click?
or is it the piece of code which doesn't appear here, but abstracts the
btnAccept_Click method?

this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click);

Many thanks for any answers to this semingly silly question.

The delegate is Click.

The only difference between
"public event EventHandler Click;" and "public EventHandler Click;"
is the operations that you are allowed to perform on the delegate from
outside the class.
From inside the class they are indistinguishable other than by reflection.

Just to confuse you, although declared as delegate, the actual base type of
EventHandler and all other delegates is actually System.MulticastDelegate
rather than System.Delegate.

Also remember that += is not an instance operation but actually effectively
something like:

Click = EventHandler.operator+(Click,handler);
rather than
Click.Add(handler);

This allows it to work with Click == null.

For the first handler add you have
Click = EventHandler.operator+(null,handler1); --> Click == handler1
If you add another you have effectively:
Click = EventHandler.operator+(handler1,handler2) --> Click == handler3
where handler3 calls handler1 and handler2
 
J

Jon Skeet [C# MVP]

Nick Hounsome wrote:

The delegate is Click.

No, that's the event. There's no guarantee that it's backed by a simple
delegate. Heck, it might not even be backed by a delegate at all
(although it would be an odd implementation which didn't have a
delegate somewhere).

The only delegate in the above statement is
new EventHandler (this.btnAccept_Click)
The only difference between
"public event EventHandler Click;" and "public EventHandler Click;"
is the operations that you are allowed to perform on the delegate from
outside the class.

No, that's not true. The first declares both a public event (with some
default access methods) *and* a private delegate field. The second
declares just a public delegate field. While the broad result is as you
say, there are other differences some of which (as you said later) you
can detect with reflection. Here's another difference which you can't
detect by reflection though - the first form will lock the monitor
associated with the object it's called on for the duration off
add/remove operations. (In C# 2.0 it could be a different monitor; in
C# 1.1 it's always the containing object or the type for a static
event.)

While events and delegates often look the same, I don't think it's a
good idea to trivialise the differences between them. The difference
between an event and a delegate field is similar to the difference
between a property and a "normal" field. The operations involved
(add/remove for events, set/get for properties) are often implemented
as "straight-through" operations on a field, but they certainly don't
have to be.

<snip>

Jon
 
N

Nick Hounsome

Jon Skeet said:
Nick Hounsome wrote:



No, that's the event. There's no guarantee that it's backed by a simple
delegate. Heck, it might not even be backed by a delegate at all
(although it would be an odd implementation which didn't have a
delegate somewhere).

You are right in that you can override the add and remove so that it doesn't
use a delegate but unless you do the event is effectively a delegate as can
be seen in the debugger.
The only delegate in the above statement is
new EventHandler (this.btnAccept_Click)


No, that's not true. The first declares both a public event (with some
default access methods) *and* a private delegate field. The second
declares just a public delegate field. While the broad result is as you
say, there are other differences some of which (as you said later) you
can detect with reflection. Here's another difference which you can't
detect by reflection though - the first form will lock the monitor
associated with the object it's called on for the duration off
add/remove operations. (In C# 2.0 it could be a different monitor; in
C# 1.1 it's always the containing object or the type for a static
event.)

A different monitor?
While events and delegates often look the same, I don't think it's a
good idea to trivialise the differences between them. The difference
between an event and a delegate field is similar to the difference
between a property and a "normal" field. The operations involved
(add/remove for events, set/get for properties) are often implemented
as "straight-through" operations on a field, but they certainly don't
have to be.

You are right but I still think that it is helpful to think of it this way
at least as a start.
 
J

Jon Skeet [C# MVP]

Nick Hounsome said:
You are right in that you can override the add and remove so that it doesn't
use a delegate but unless you do the event is effectively a delegate as can
be seen in the debugger.

Well, I find it helpful to think of it as both a delegate and an event.
From the outside of the class it looks like an event, from the inside
of the class it looks like a delegate. (I haven't actually checked
whether if you use += or -= within the class, it uses the event or the
delegate.)
A different monitor?

Yes. In 1.1 it always uses:

lock (this)
{
theDelegate += value;
}

etc

In 2.0 the compiler is free to introduce another variable to hold a
monitor to lock on:

lock (compilerGeneratedVariable)
{
theDelegate += value;
}
You are right but I still think that it is helpful to think of it this way
at least as a start.

I think we'll have to agree to disagree. I tend to find that if you
tell someone something that's wrong to start with, even if it's meant
to simplify things for the moment, it causes confusion later on.
 
G

Guest

Hi guys, thanks for the thoughts. Just to muddy the water further. So far
this is my understanding:

//The real delegate is that which is declared:

delegate void realDelegate(int someParameter);

//Then when you want to use it, you *delegate* something to it by doing this:

someEvent += new realDelegate(someArgument);

//so that 'new realDelgate(someArgumant)' is the delegate only in that it's
delegating the event to the delegate (the abstracted method) which it
instantiates with the new keyword . So it (+= new...) is only called the
delegate because it is delegating to the delegate, but is referred to as the
delegate for simplicity.

Would this be a correct assumption or am I way off the mark?

Thanks
Ant
 
J

Jon Skeet [C# MVP]

Ant said:
Hi guys, thanks for the thoughts. Just to muddy the water further. So far
this is my understanding:

//The real delegate is that which is declared:

delegate void realDelegate(int someParameter);

That's the delegate type.
//Then when you want to use it, you *delegate* something to it by doing this:

someEvent += new realDelegate(someArgument);

new realDelegate(someArgument) is the delegate instance.
//so that 'new realDelgate(someArgumant)' is the delegate only in that it's
delegating the event to the delegate (the abstracted method) which it
instantiates with the new keyword . So it (+= new...) is only called the
delegate because it is delegating to the delegate, but is referred to as the
delegate for simplicity.

Would this be a correct assumption or am I way off the mark?

I think you're making it more complicated than it needs to be. I think
"delegate" is generally used for both the type and an instance of the
type, but disambiguating with "delegate type" or "delegate instance" is
good enough (and is what the C# spec uses).

Jon
 

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