Events vs. Delegates

N

Nick Hounsome

M

Mike

Nick Hounsome said:
[cut]
And a delegate is no more a class than an interface is -- except that a
delegate *is* implemented by creating a seperate class of the same name
as the delegate with an Invoke() method. Is this the only possible
implementation of a delegate?
If I say "c.Click += myMethod;", what do I care if it's through the
current event keyword, or if c.Click is a property that returns a static
Event object that implements the "+" operation?

[cut]

Language interoperability requires that, at the very least, events are
implemented as the add_X and remove_X methods - You can ask for a change
to what goes on behind that in C# if you want because it's just cosmetic
but changing to a property that contains an event object would break all
existing language interoperability.

I'm not sure why everyone thinks I'm asking for a change in such a used
aspect of C# ex post facto -- as this is (a) not what I want and (b) futile.
I was just saying that if "event" were not there, there already exist other
language features (in concert with tools) that could have acheived similar
(if perhaps not exact) results in a more general and extensible way. Any
functionality not acheived (such as Invoke operation hiding) could be
addressed by simlarly general alternate language features (such as more
flexible field access control), rather than being specific to "event". I
think c# is great and I do not bebrudge its designers for making an
expedient and very workable choice with "event" -- I didn't expect defensive
refactions, especially as I'm usually defending c# myself, as I think it has
in general very "well-balanced" in such choices.

thanks,
m
 
J

Jon Skeet [C# MVP]

I think c# is great and I do not bebrudge its designers for making an
expedient and very workable choice with "event" -- I didn't expect
defensive refactions, especially as I'm usually defending c# myself,
as I think it has in general very "well-balanced" in such choices.

I suspect the reaction was the way it was partly because there's a big
difference between "expedient and very workable" and "a wart and a lot
of hacky sugar for very little gain". Many of us rather like the sugar,
just as many of us like properties even though they offer nothing that
can't be done with get and set methods. (Not that the property syntax
is perfect either, of course - at least in 2.0 you can specify
different access levels, at last...)
 
D

Daniel O'Connell [C# MVP]

Nick Hounsome said:
Daniel said that modifying add/remove behaviour isn't common but it is for
every component as they all modify it to use a common dictionary rather
than having individual delegate fields.

I'd also bet the framework component's itself are just about the only place
its used, and although the framework is very big, I doubt it stands as much
compared to the rest of the world's .NET codebase. It makes alot of sense
with alot of events and in the rare occasion you need very carefully
designed locking semantics, but beyond that, the everyday user isn't going
to use it, the power user isn't going to use it, pretty much no one will.
The framework also makes extensive use of unsafe code and pinvoke, that
doesn't make it common either.
 
N

Nick Hounsome

Daniel O'Connell said:
I'd also bet the framework component's itself are just about the only
place its used, and although the framework is very big, I doubt it stands
as much compared to the rest of the world's .NET codebase. It makes alot
of sense with alot of events and in the rare occasion you need very
carefully designed locking semantics, but beyond that, the everyday user
isn't going to use it, the power user isn't going to use it, pretty much
no one will. The framework also makes extensive use of unsafe code and
pinvoke, that doesn't make it common either.

If you design a user control and add properties why wouldn't you use the
functionality in the base class? I must admit I haven't until now but I
think that I probably will in future.

I admit that I don't know of any other use for it so if you really want new
functionality perhaps you can just ask for this specific mode of operation
to be built in as an option somehow (an attribute would work).
 
J

Jon Skeet [C# MVP]

Daniel O'Connell said:
I'd also bet the framework component's itself are just about the only place
its used, and although the framework is very big, I doubt it stands as much
compared to the rest of the world's .NET codebase. It makes alot of sense
with alot of events and in the rare occasion you need very carefully
designed locking semantics, but beyond that, the everyday user isn't going
to use it, the power user isn't going to use it, pretty much no one will.
The framework also makes extensive use of unsafe code and pinvoke, that
doesn't make it common either.

Personally I regularly change the add/remove behaviour - but only
because the default behaviour isn't nicely thread-safe :(
 
M

Mike

Jon Skeet said:
I suspect the reaction was the way it was partly because there's a big
difference between "expedient and very workable" and "a wart and a lot
of hacky sugar for very little gain".

Fair enough :) -- certainly from an emotional standpoint.
I don't think the two statements (or at least the two sentiments) cannot
co-exist, though.
Although I should have been more careful - probably it was overly strong.
Many of us rather like the sugar,
just as many of us like properties even though they offer nothing that
can't be done with get and set methods. (Not that the property syntax
is perfect either, of course - at least in 2.0 you can specify
different access levels, at last...)

Sure - I'm not saying there's isn't a line above which things are certainly
worth it, and I think properties are above it; I think now "events" are
above it, but just barely...

thanks,
m
 
K

Kevin Spencer

Hi Mike,
Sure - I'm not saying there's isn't a line above which things are
certainly worth it, and I think properties are above it; I think now
"events" are above it, but just barely...

Well, performance isn't everything. There is also good reason for adopting
more or less universally-accepted practices. It makes code maintenance
easier for anyone who may have to pick up where someone else left off,
including the original author. And it makes using Reflection much easier
when necessary. Consistency of technique is a human resource-saving
(time-saving) factor.

As we programmers are more or less paid "by the hour" (one way or the
other), anything that optimizes *our* performance is definitely a
consideration with regards to cost!

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer

Presuming that God is "only an idea" -
Ideas exist.
Therefore, God exists.
 
M

Mike

Daniel - this thread is luckilly winding down, but I didn't want to leave
this reply completely hanging, so I'll address remaing stuff...

Daniel O'Connell said:
No, modifying add/remove behavior isn't very common, which is why the
add/remove accessors are pretty unknown. That doesn't really relate to
anything at all though. Your point here seems to be "if they want to
control add and remove, let them write their own framework" which is
terrible, IMHO.

IMHO, as well. I did not suggest (or didn't think I did) any such thing. I
suggested that they
could make use of nearly equally easy-to-use framework that would exist in a
system sans the event keyword, but possibly with other language mods in
place of "event", but supporting
the event model, as well as non-event code.
Basic eventing covers it very well without any pointless complications.
Agreed.


Obviously. You seem upset

No, I am not upset.
I can't see why you bothered to post at all after your question was
answered if you didn't have an issue with the existing implementation.

I had no question, I just thought it was an interesting topic (current
"event" keyword vs. alternate event implementations) - perhaps it is not.
I guess I should have posted to comp-lang-csharp-random-musings...
It saves you no time because you clearly don't actually write them. Have
you ever written a class that *EXPOSES* events

Of course.
Yes, you have failed. You seem to be just shooting in the dark
against something you don't like.

Hey, I think you started shooting.
Wow. You've needed events *ONCE* and you couldn't use it, so it must be
bad eh? I'm sorry, you really don't seem to have used them enough to even
have a leg to stand on here, no offense intended.

Sorry - I should have been more clear. What I said was
"When I could have used 'event' as a notification
source" -- what I meant was
"When I could have used 'event' as a *general* notification
source *outside of the domain of GUI controls*". (A more general
publish/subscribe
scenerio.) All I was saying was I had to abandon the existing language
feature because
it was really close, but not extensible. A alternate event object
implementation could have been extended.
However, I agree that it's not a strong statement from the vantage point of
the existing "event" keyword
for me to say it wasn't useful for something that it wasn't designed for -
execpt that's not the vantage point I had.
There is definatly more to it than generality, its what is most useful.
The complicated, general solution isn't always the right one, infact it's
probably the wrong one. Simple and static is almost always better than
complicated and general.

I would agree with you here in many cases.
I disagree with your first conclusion. That is my #2 complaint with Java,
it lacks first class events and makes up for it with a hackneyed,
difficult to follow system(especially when anonymous classes are
involved.) The only thing worse is the lack of first class properties.

Yes, the anoymous class cruft gets pretty old - at least c# delgates hide
the
class definition from the user.
Macro's and meta-programming is something I hope the language never has.
That is almost always the first sign that the language has outgrown its
value.

I'm not sure I agree with that, exactly, as they are usually an integral
part
of the language from the start, so I'm not sure how the life-cycle
charaterization fits it. But macros can be both incredibly ugly and abused,
as well as extremely useful when they're needed. It's almost the opposite
life-cycle for marco's in the C-like languages -
they appeared first, and then many uses of macros (and typedef) are replaced
by the cleaner generics and/or templates, to the point where c# and Java
don't have macros them at all. (Although I still think Typedef would be nice
to have - even when
generics are a possible fit, you end up with recursive <T...> creep in all
your definitions. At least for
simple cases like defining the size of an integer that may need to change
from 16 to 32 bits, for example, I think typedef is a good fit.)
And your uses of reflection don't really apply to much I've done
personally. I don't see the point in inspecting something I knew about
already.

I was thinking of common examples such as automatically wrapping public
members in possibly renamed
properties (e.g, for O/R mappers or data-binding controls that only look at
properties), providing proxy classes that provide an inplementation for an
interface that the object doesn't natively support, etc.
Again, not that it's the best way in an ideal world to accomplish the task,
it's just what's in the toolbox.
(As well as source-to-source transformation, a la Codesmith, etc.)
IMHO, both solutions have problems.
I don't think your method is necessarily the best either.

I never said it was the best.
Personally I
find it too complex with no added value.

It *is* more complex, but not from the subscriber's POV, which I think is
the important part.
The provider's implemetation can also be mostly pre-baked.

I presented some added value, but I'm okay with someone not agreeing that
the trade-off's are worth it.

thanks,
m
 
D

Daniel O'Connell [C# MVP]

Mike said:
Daniel - this thread is luckilly winding down, but I didn't want to leave
this reply completely hanging, so I'll address remaing stuff...

I have the same opinion here, except I still have points to make. Perhaps
the thread isn't quite dead yet.

IMHO, as well. I did not suggest (or didn't think I did) any such thing. I
suggested that they
could make use of nearly equally easy-to-use framework that would exist in
a
system sans the event keyword, but possibly with other language mods in
place of "event", but supporting
the event model, as well as non-event code.

Certainly. I mistook some of your early approach.
I had no question, I just thought it was an interesting topic (current
"event" keyword vs. alternate event implementations) - perhaps it is not.
I guess I should have posted to comp-lang-csharp-random-musings...

Sorry, you realy never implied it was merely intellectual exercise(which I
don't mind, mind you.) You came across as someone who wanted change, not
someone who was interested in the why's.
Sorry - I should have been more clear. What I said was
"When I could have used 'event' as a notification
source" -- what I meant was
"When I could have used 'event' as a *general* notification
source *outside of the domain of GUI controls*". (A more general
publish/subscribe
scenerio.) All I was saying was I had to abandon the existing language
feature because
it was really close, but not extensible. A alternate event object
implementation could have been extended.
However, I agree that it's not a strong statement from the vantage point
of the existing "event" keyword
for me to say it wasn't useful for something that it wasn't designed for -
execpt that's not the vantage point I had.

It's lack of extensibility is probably a saving grace there. Event's as
simple devices are a big part of their beauties. Some of the research I did
turned up people who wanted to use events for uses that start out very close
to eventing but eventually drifts. An alternate approach could well be the
better choice no matter how extensible the eventing model is.
I'm not sure I agree with that, exactly, as they are usually an integral
part
of the language from the start, so I'm not sure how the life-cycle
charaterization fits it. But macros can be both incredibly ugly and
abused,
as well as extremely useful when they're needed. It's almost the opposite
life-cycle for marco's in the C-like languages -
they appeared first, and then many uses of macros (and typedef) are
replaced by the cleaner generics and/or templates, to the point where c#
and Java don't have macros them at all. (Although I still think Typedef
would be nice to have - even when
generics are a possible fit, you end up with recursive <T...> creep in all
your definitions. At least for
simple cases like defining the size of an integer that may need to change
from 16 to 32 bits, for example, I think typedef is a good fit.)

Interestingly enough, typedef does exist in teh form of using aliases. The
distinction is that the language has no concept of a header file or a global
definition file. In C++, typedef's appear to work across files because the
header file was included. Adding that to the language would be unattractive,
although a using modifier of some sort would have its ups(although I do find
typedefs to be a bit dangerous sometimes.)

As for metaprogramming, atleast in the sense that C++ and its template
engine uses, or perhaps I should say the sense in which C++'s template
engine is used, is as bad as macro's, IMHO. Hidden code that can produce
volumious errors and code too tight and complex to debug. I'd rather have to
write it all out and let the runtime do a little heavy lifting than have a
facility in the language that can make that much of a mess with benefits
that don't apply too much. I just don't consider it a good choice for
mainstream languages, and would, I suspect, eventually spell the end for the
broad value of the language. Although one could probably argue that LINQ
steps into metaprogramming in some senses since various bits of the
implementation might produce another "program," in a sense, to do the work,
however, due to its general design I'd probably not go so far as to say
that. Any sort of program generation\metaprogramming support that may exist
in it would largely be a behind the scenes sort of deal, something library
implemented using a langauge feature moreso than language implemented. Bit
of a tough distiction there, I'd say, but I'd side away from it in much the
same way.
I was thinking of common examples such as automatically wrapping public
members in possibly renamed
properties (e.g, for O/R mappers or data-binding controls that only look
at
properties), providing proxy classes that provide an inplementation for an
interface that the object doesn't natively support, etc.
Again, not that it's the best way in an ideal world to accomplish the
task, it's just what's in the toolbox.
(As well as source-to-source transformation, a la Codesmith, etc.)
IMHO, both solutions have problems.

Hmm. I can see your point here, still, we are talking a rather small
percentage of code(outside of perhaps databinding, which simply has to be
reflection based(outside of using some kind of complex data source
interface, which, IIRC, exists in some form anyway.)
 

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