Events vs. Delegates

G

Guest

Hi,

I am new to C# (with long year experience in C++) and I am a bit confused by
the language construct of events. What is it I can do with events that I
cannot do with delegates? At the moment it seems to me that Microsoft has
developed similar functionality via two keywords. I do understand that an
event offers better encapsulation as the underlying delegate is private, but
is that all ?
 
D

Daniel O'Connell [C# MVP]

Burkhard said:
Hi,

I am new to C# (with long year experience in C++) and I am a bit confused
by
the language construct of events. What is it I can do with events that I
cannot do with delegates? At the moment it seems to me that Microsoft has
developed similar functionality via two keywords. I do understand that an
event offers better encapsulation as the underlying delegate is private,
but
is that all ?

Well, the encapsulation is really the important part. Allowing outside
clients the ability to clear or execute events is just not acceptable.

However, event and delegate, while they look the same, work differently.
Event's are basically a type of property that offers a standard set of
accessors to the outside world, add, remove, and optionally raise(although
the spec allows for arbitrary accessors.) They also stand out in metadata as
events and not just as a field of type delegate which does have some
semantic value. An event is something you can subscribe to freely, whereas a
delegate doesn't offer that type of definition. Delegate fields can and are
used for other purposes fairly often.

Put simply, an event is an event, whereas a delegate only might be.
 
P

Peter Rilling

Events are field (well, not always, but mostly), Delegates are classes.
Event are just "containers" for one or more delegates. When an event
happens, all the delegates registered for a particular event are called. A
delegate is a function pointer which points to the "callback" function used
to handle the event.

They are completely different and have no similar functionality, but they
are used together so that the raising of an event calls one of your methods.

Delegates are never private (never say never). They will most always be
public because your code needs to be able to create an instance of them.

Things are a little bit more complicated than what I have said, but this
should give you an idea that they are different. Events and delegates are
no more similar than an enum and a property.
 
J

Jon Skeet [C# MVP]

Burkhard said:
I am new to C# (with long year experience in C++) and I am a bit confused by
the language construct of events. What is it I can do with events that I
cannot do with delegates? At the moment it seems to me that Microsoft has
developed similar functionality via two keywords. I do understand that an
event offers better encapsulation as the underlying delegate is private, but
is that all ?

Think of it like fields and properties, except that for events in C#
there happens to be a shorthand way of writing the common code.

You need a field (or *something*) to store the delegate references to
call, but the event itself is just a pair of methods (for subscribing
and unsubscribing) just as the property itself is just a pair of
methods for getting/setting the value. It's easier to understand this
when you see what a "field-like event" declaration is compiled to.

public event EventHandler Foo;

is compiled to two parts. One is a field:

private EventHandler FooField;

and one is the event itself:

public event EventHandler Foo
{
add
{
lock (this)
{
FooField += value;
}
}
remove
{
lock (this)
{
FooField -= value;
}
}
}

Now, a few notes:

1) FooField is *actually* a field with name Foo. I've just called it
FooField here for clarity. The C# compiler wouldn't actually let you
explicitly declare a field with the same name as the event.

2) The "lock(this)" is true with C# 1.1, but may not be true in 2.0 -
it's up to the compiler to decide what to lock on in 2.0. To my mind,
neither of these are really great. See
http://www.pobox.com/~skeet/csharp/threads/lockchoice.shtml
 
G

Guest

Actually,

the event keyword is used to create a delegate - an event delegate -- you
just don't use the "new" keyword.

So for example the line:

public event MouseEventHandler handler;

would create an instance of a MouseEventhandler delegate whose signature
might look like this:

public delegate void MouseEventHandler(object source, MouseEventArgs args);

The event keyword tells the compiler that this delegate instance is an event.

Peter
 
J

Jon Skeet [C# MVP]

Peter Bromberg said:
the event keyword is used to create a delegate - an event delegate -- you
just don't use the "new" keyword.

So for example the line:

public event MouseEventHandler handler;

would create an instance of a MouseEventhandler delegate whose signature
might look like this:

No, that doesn't create any instances of the MouseEventHandler
delegate. It creates an instance field of type MouseEventHandler, along
with an event of the same name and type. No instances are created,
however - the default value is null (just as for other reference type
variables).
 
M

Mike

Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines (or
more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

That's what attributes are made for.

As for the Interface contract, the framework need just define:
interface IEventSource { Add(...); Remove(...); ... }
and:
class EventSource : IEventSource { /* handle add/remove */ /* overload
+ */ /* etc...*/ }

and replace:

interface IFoo { event DelegateType TheEvent; event DelegateType2
TheEvent2;...
with
interface IFoo { EventSource TheEvent {get;} ; EventSource TheEvent2
{get;} ; ...

and Bob's your uncle...

This needs no extra language features (like an "event" keyword), has no more
"source bulk", and is much more explict. (With the "event" keyword you just
have to "know" there's a property-like field created - here it's explicit,
and the add/remove code is implemented in a proper object (which you can
provide if you like), and not in a hacked (and hidden, unless you know to
override) "add"/"removed" sections of the generated event code.)
You could also use generics if you wanted to keep the typing of the
delegate, but this isn't necessary seeing with an "event" handler your are
typically forced to using (EventSource, EventArgs) anyway. Still, it would
probably be nice to allow:

interface IFoo { TEventSource<DelegateType> TheEvent {get;} ;
TEventSource <DelegateType2> TheEvent2 {get;} ; ...

where the normal EventSource is already "specialized" on a (Sender,
EventArgs) delegate.

m
 
D

Daniel O'Connell [C# MVP]

Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines (or
more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

That's what attributes are made for.

As for the Interface contract, the framework need just define:
interface IEventSource { Add(...); Remove(...); ... }
and:
class EventSource : IEventSource { /* handle add/remove */ /* overload
+ */ /* etc...*/ }

and replace:

interface IFoo { event DelegateType TheEvent; event DelegateType2
TheEvent2;...
with
interface IFoo { EventSource TheEvent {get;} ; EventSource TheEvent2
{get;} ; ...

and Bob's your uncle...

This needs no extra language features (like an "event" keyword), has no
more "source bulk", and is much more explict. (With the "event" keyword
you just have to "know" there's a property-like field created - here it's
explicit, and the add/remove code is implemented in a proper object (which
you can provide if you like), and not in a hacked (and hidden, unless you
know to override) "add"/"removed" sections of the generated event code.)
You could also use generics if you wanted to keep the typing of the
delegate, but this isn't necessary seeing with an "event" handler your are
typically forced to using (EventSource, EventArgs) anyway. Still, it would
probably be nice to allow:


Isn't that alot of extra code(and extra logic for compilers and code
analysers) for virtually no benefit? The CLR itself defines events, there is
metadata, an extensible set of accessors, and explicit rules tied to them,
they are as first class as methods, properties, and fields within the
runtime. If you read up on the language, runtime, or anything else it will
become clear.

Beyond that, your solution is not more explicit, it hides things behind a
class most users won't realize you can dig into(or forces them to write more
classes , which to my mind *IS* code bloat,) forces the end user to write
properties(which the current mechanism doesn't) and it uses an attribute,
which, IMHO, is the #1 wrong thing to do with any first class language
feature. Attributes should apply only metadata, and with very few
exceptions, not change the meaning of a line of code. By using an attribute
to define semantics you complicate the use of the language, if not the
language itself, with artificial markers. I think the current method is far
better than the one you suggest here.
 
J

Jon Skeet [C# MVP]

Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines (or
more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

There's a *very* big different. With the first, *anyone* can change the
field, to anything - no restrictions. With the second, you've only got
subscribe/unsubscribe. They encapsulate different things.

<snip>
 
M

Mike

Daniel O'Connell said:
Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines
(or more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

That's what attributes are made for.

As for the Interface contract, the framework need just define:
interface IEventSource { Add(...); Remove(...); ... }
and:
class EventSource : IEventSource { /* handle add/remove */ /*
overload + */ /* etc...*/ }

and replace:

interface IFoo { event DelegateType TheEvent; event DelegateType2
TheEvent2;...
with
interface IFoo { EventSource TheEvent {get;} ; EventSource TheEvent2
{get;} ; ...

and Bob's your uncle...

This needs no extra language features (like an "event" keyword), has no
more "source bulk", and is much more explict. (With the "event" keyword
you just have to "know" there's a property-like field created - here it's
explicit, and the add/remove code is implemented in a proper object
(which you can provide if you like), and not in a hacked (and hidden,
unless you know to override) "add"/"removed" sections of the generated
event code.)
You could also use generics if you wanted to keep the typing of the
delegate, but this isn't necessary seeing with an "event" handler your
are typically forced to using (EventSource, EventArgs) anyway. Still, it
would probably be nice to allow:


Isn't that alot of extra code(and extra logic for compilers and code
analysers) for virtually no benefit?

Obviously, I don't think so :)
(A) It's not extra code (the # of chars is pretty close (8 more chars?), as
above)
(B) Most of this boilerplate code is generated for you anyway
The CLR itself defines events, there is metadata

The metadata can exist in either scheme, as with [Event...] above.
, an extensible set of accessors, and explicit rules tied to them,

Exactly - those rules need not be there.
they are as first class as methods, properties, and fields within the
runtime. If you read up on the language, runtime, or anything else it will
become clear.

I understand your viewpoint - but your reply to me seems to be:
"your idea that events should not be first-class is wrong, because they are"
doesn't seem to go anywhere.
Beyond that, your solution is not more explicit,

Huh? *Nothing* is hidden. All class and interfaces are mentioned explicitly.
This is in contrast to the event where an event declaration goes ahead and
creates lots of crap behind the scenes,
including a property-like definition with add/remove sections that could
easily be normal method invocations.
it hides things behind a class most users won't realize you can dig into

Well, there's no reason for most users to "dig into" it at all - it just
works, and appears from the client's perspective just like the current
events, with += and the like. If advanced users want to add functionality to
an event (let's say "ClearAll()" or "SetInvokeThreadingMode(...)" or
"SetInvokeExceptionChainMode(...) or whatever) they now have a class to
extend or replace - where with the currnent model add{} and remove{} are set
in stone. (At least from the c#-side, maybe not from the CLR's perspective.)
forces them to write more classes

Not that I can see - the event classes/interfaces would all be in the
framework.
forces the end user to write propertis(which the current mechanism
doesn't)

People define properties at the drop of a hat, mostly when not necessary -
why then allow public access to your event field?
it uses an attribute, which, IMHO, is the #1 wrong thing to do with any
first class language feature.

True - but again, not a problem if they aren't first-class...
Attributes should apply only metadata, and with very few exceptions, not
change the meaning of a line of code.

It does not change the meaning of the code -- the Event metadata is only for
tools that wish to use it. (Intellisense, etc.)
By using an attribute to define semantics you complicate the use of the
language, if not the language itself, with artificial markers. I think the
current method is far better than the one you suggest here.

Again, I don't see where I led you to beleive the attribute had any effect
on semantics or generated code at all.
The whole point of my post is that we can get by with existing (excluding
the event keyword) language features only, and end up with a much more
general system.

I'm not ready to ship my my ten-minute design by any means - I'm just saying
I think we'd all live without the "event" keyword.
I'm not saying it's horrible - I think c# is great. It's just weather you
think a certain feature is above or below the line of being necessary - and
I think people are split on this particular one. Although I stay away from
GUI's as much as possible, I can see that if you were programming GUI's all
the time and did not have good tool support, that you'd want to minimize
what is necessary to get basic events working.

m
 
M

Mike

Jon Skeet said:
Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines
(or
more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

There's a *very* big different. With the first, *anyone* can change the
field, to anything - no restrictions. With the second, you've only got
subscribe/unsubscribe. They encapsulate different things.

Yes - I provided a mixed model that isn't exactly what I had in mind - I
supposed I shouldn't have posted if I wasn't will to put up a design that
reflected my thinking - I suppose in my copious spare time, I'll try and do
so. In this case the delegate should be black-boxed by a class (framework
provided, if desired) that exposes only subscribe/unsubscribe, if that is
desired, and the attribute belongs on the field/property that returns the
EventSource, not on the delegate field itself, unless simple, unrestricted
access is permitted. (I conflated some of the event provider and client code
in my post.)

m
 
D

Daniel O'Connell [C# MVP]

Mike said:
Daniel O'Connell said:
Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines
(or more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

That's what attributes are made for.

As for the Interface contract, the framework need just define:
interface IEventSource { Add(...); Remove(...); ... }
and:
class EventSource : IEventSource { /* handle add/remove */ /*
overload + */ /* etc...*/ }

and replace:

interface IFoo { event DelegateType TheEvent; event DelegateType2
TheEvent2;...
with
interface IFoo { EventSource TheEvent {get;} ; EventSource TheEvent2
{get;} ; ...

and Bob's your uncle...

This needs no extra language features (like an "event" keyword), has no
more "source bulk", and is much more explict. (With the "event" keyword
you just have to "know" there's a property-like field created - here
it's explicit, and the add/remove code is implemented in a proper object
(which you can provide if you like), and not in a hacked (and hidden,
unless you know to override) "add"/"removed" sections of the generated
event code.)
You could also use generics if you wanted to keep the typing of the
delegate, but this isn't necessary seeing with an "event" handler your
are typically forced to using (EventSource, EventArgs) anyway. Still, it
would probably be nice to allow:


Isn't that alot of extra code(and extra logic for compilers and code
analysers) for virtually no benefit?

Obviously, I don't think so :)
(A) It's not extra code (the # of chars is pretty close (8 more chars?),
as above)
(B) Most of this boilerplate code is generated for you anyway

It still requires overriding a concrete class or implementing an interface
to change add/remove behavior.
The CLR itself defines events, there is metadata

The metadata can exist in either scheme, as with [Event...] above.
Certainly it could, but why? For something that is probably more common than
a great many other features(like stackalloc or static classes, for example,)
this lacks any reason. Do you *HAVE* a reason that this is better? Or do you
just think it is because its teh way you expected it to be?
Exactly - those rules need not be there.

They'd clearly have to exist, they'd just be different. Instead of event
metadata, you'd have a rule about the type of event container you'd have to
use or what have you. it's still there.
I understand your viewpoint - but your reply to me seems to be:
"your idea that events should not be first-class is wrong, because they
are" doesn't seem to go anywhere.

You're suggestion here has basically been "its wrong because I say so."
You've offered nothing as far as evidence or reasoning, except that you
weren't aware of something that you really don't need to be aware of. Events
deserve to be first class features, they offer semantic value and are quite
commonly used, IMHO.
Huh? *Nothing* is hidden. All class and interfaces are mentioned
explicitly.
This is in contrast to the event where an event declaration goes ahead and
creates lots of crap behind the scenes,
including a property-like definition with add/remove sections that could
easily be normal method invocations.

That is sugar to save you time. Its not like the langauge designers are
going out of hteir way to make sure you don't know about the add/remove
accessors.
Well, there's no reason for most users to "dig into" it at all - it just
works, and appears from the client's perspective just like the current
events, with += and the like. If advanced users want to add functionality
to an event (let's say "ClearAll()" or "SetInvokeThreadingMode(...)" or
"SetInvokeExceptionChainMode(...) or whatever) they now have a class to
extend or replace - where with the currnent model add{} and remove{} are
set in stone. (At least from the c#-side, maybe not from the CLR's
perspective.)

This is pretty irrelevent. Is your argument really "it works the same, so
why not?" All of your suggestions basically are going to make things harder
on everyone. The current model has none of htese features because they
aren't needed. There is no concept of threading mode or invocation mode. All
of that is pretty advanced I'll give you, but it is alot of complicated
machinary for very little benefit, IMHO. Anything that requires that
complicated of an invocation model probably shouldn't be using events as
they stand(a COM\Java like event sink mechanism would be my recommendation.)
Not that I can see - the event classes/interfaces would all be in the
framework.

Unless they want to change the way it stores or validates anything, that is.
If it want's to handle add, remove, or anything else you've got to derive a
class(probably an inner class as well, since you might want access to the
local fields).
People define properties at the drop of a hat, mostly when not necessary -
why then allow public access to your event field?

Come again? I don't get what you are implying here.
True - but again, not a problem if they aren't first-class...

Yet you've yet to come up with any reason why it shouldn't be.
It does not change the meaning of the code -- the Event metadata is only
for tools that wish to use it. (Intellisense, etc.)
It does change the meaning. An event is a far different thing than a
property. It is conceptually a notification sink and is treated as such *IN
CODE*. Thus the attribute changes the meaning of the property and any code
that uses it and, therefore, defines semantics.
Again, I don't see where I led you to beleive the attribute had any effect
on semantics or generated code at all.
The whole point of my post is that we can get by with existing (excluding
the event keyword) language features only, and end up with a much more
general system.

You can get by with quite a few more general features alone. You can throw
away properties and define a Property<T> type that has optional get & set
methods. You could do away with iterators, return values, operators,
delegates, and a whole host of other things as well. The point of it all
isn't that you *CAN* get rid of it, the point is that it is easier and\or
permits new scenarios with no costs on any level.
I'm not ready to ship my my ten-minute design by any means - I'm just
saying I think we'd all live without the "event" keyword.
I'm not saying it's horrible - I think c# is great. It's just weather you
think a certain feature is above or below the line of being necessary -
and I think people are split on this particular one. Although I stay away
from GUI's as much as possible, I can see that if you were programming
GUI's all the time and did not have good tool support, that you'd want to
minimize what is necessary to get basic events working.

People are split? You are the first person I've ever seen suggest events
don't need to be there. They are incredibly simple, distinction from
delegate and events excluded, I really don't get your problem with them. You
seem just to think they are a bad idea.
 
W

William Stacey [MVP]

I see what your saying and have wondered on that from time to time. But with the event modifier you get this for ~free:
1) You can't invoke a event from outside the class that contains the event delegate.
2) You can include an event in a interface. In contrast, you could not add a plain delegate (or class) to an interface as you can't add fields to an interface.
3) You can't assign an Event to a "plain" delegate var and run it to get around the invoke restrictions.
4) You can't make an assignment to an Event from outside the containing class (i.e. external readonly).
5) You don't "see" properties on the type that you can't call. Actually, you don't "see" any members on events from intellisense.

Those would be hard or impossible to do by containing a delegate in a Event class. Below Event class is an example:
public sealed class Event

{

private EventHandler del;



public Event()

{

}



public int Count

{

get

{

EventHandler temp = del;

if ( temp == null )

return 0;

return temp.GetInvocationList().Length;

}

}



public void Add(EventHandler del)

{

this.del += del;

}



public void Remove(EventHandler del)

{

this.del -= del;

}



public void RemoveAll()

{

this.del = null;

}



public static Event operator +(Event e, EventHandler eventHandler)

{

if (e == null)

return null;

e.Add(eventHandler);

return e;

}



public static Event operator -(Event e, EventHandler eventHandler)

{

if (e == null)

return null;

e.Remove(eventHandler);

return e;

}



internal Delegate[] GetInvocationList()

{

EventHandler temp = this.del;

if (temp == null)

return new Delegate[0];

return temp.GetInvocationList();

}



internal void Invoke(object sender, EventArgs e)

{

EventHandler temp = this.del;

if (temp == null)

return;



foreach (EventHandler eh in temp.GetInvocationList())

{

try

{

eh(sender, e);

}

catch

{

// Do something with exception.

}

}

}

}


This gets you "close", but still has some problems:
1) You don't get the normal delegate semantics. You need to call event.Invoke(), instead of just event().
2) You don't get the readonly semantics for external access.
3) You still can't put Event in an interface.
4) You don't get Invoke protection from external code.
5) The internal for Invoke is a hack. It also means you need to define Event yourself in all assemblies that would use Event.
You may be able to some kind of runtime check, but that would slow your events down.
6) External code can pass around the Event ref - which may not be a good thing.
7) Your "bake" in the EventHandler delegate. Not sure how to make this more generic to handle any delegate. You could use EventHandler<T> is guess.

In the end, I think they made the right choice.

--
William Stacey [MVP]

|
| | >> Personally, "event" seems like a wart and a lot of hacky sugar for very
| >> little gain, and some restrictions that may be limiting.
| >>
| >> I think just plain delegates, and an [Event...] attribute for delegate
| >> fields for tools that like to distingish events would have done just as
| >> well.
| >>
| >> Certainly, there's not much difference bettween typing these two lines
| >> (or
| >> more likely, having the IDE do it for you):
| >>
| >> [Event] public DelegateType Field;
| >> public event DelegateType Field;
| >
| > There's a *very* big different. With the first, *anyone* can change the
| > field, to anything - no restrictions. With the second, you've only got
| > subscribe/unsubscribe. They encapsulate different things.
|
| Yes - I provided a mixed model that isn't exactly what I had in mind - I
| supposed I shouldn't have posted if I wasn't will to put up a design that
| reflected my thinking - I suppose in my copious spare time, I'll try and do
| so. In this case the delegate should be black-boxed by a class (framework
| provided, if desired) that exposes only subscribe/unsubscribe, if that is
| desired, and the attribute belongs on the field/property that returns the
| EventSource, not on the delegate field itself, unless simple, unrestricted
| access is permitted. (I conflated some of the event provider and client code
| in my post.)
|
| m
|
|
| >
| > <snip>
| >
| > --
| > Jon Skeet - <[email protected]>
| > http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
| > If replying to the group, please do not mail me too
|
|
 
N

Nick Hounsome

Mike said:
Jon Skeet said:
Mike said:
Personally, "event" seems like a wart and a lot of hacky sugar for very
little gain, and some restrictions that may be limiting.

I think just plain delegates, and an [Event...] attribute for delegate
fields for tools that like to distingish events would have done just as
well.

Certainly, there's not much difference bettween typing these two lines
(or
more likely, having the IDE do it for you):

[Event] public DelegateType Field;
public event DelegateType Field;

There's a *very* big different. With the first, *anyone* can change the
field, to anything - no restrictions. With the second, you've only got
subscribe/unsubscribe. They encapsulate different things.

Yes - I provided a mixed model that isn't exactly what I had in mind - I
supposed I shouldn't have posted if I wasn't will to put up a design that
reflected my thinking - I suppose in my copious spare time, I'll try and
do so. In this case the delegate should be black-boxed by a class
(framework provided, if desired) that exposes only subscribe/unsubscribe,
if that is desired, and the attribute belongs on the field/property that
returns the EventSource, not on the delegate field itself, unless simple,
unrestricted access is permitted. (I conflated some of the event provider
and client code in my post.)

Your solution seems to intriduce an unnecessary extra object with associated
allocation and deallocation overhead.

The thing to remember is that an event is not an object any more than a
property is - it is just a set of methods to access private fields of the
containing class.
 
M

Mike

It still requires overriding a concrete class or implementing an interface
to change add/remove behavior.

Sure -- which happens to be the way you implement functionality everywhere
else in the language.
Modifying add/remove behavior is not all that common AFAIKT, and if you want
more control you can just use delegates and your own notification framework
and forego events all-together. In the case of overriding add/remove
behavior, you're "burdening" the control/framework writer, not the
consumer/subscriber.
The CLR itself defines events, there is metadata

The metadata can exist in either scheme, as with [Event...] above.
Certainly it could, but why? For something that is probably more common
than a great many other features(like stackalloc or static classes, for
example,) this lacks any reason. Do you *HAVE* a reason that this is
better? Or do you just think it is because its teh way you expected it to
be?
Exactly - those rules need not be there.

They'd clearly have to exist, they'd just be different. Instead of event
metadata, you'd have a rule about the type of event container you'd have
to use or what have you. it's still there.

I think somehow we just violently agreed.
You're suggestion here has basically been "its wrong because I say so."

No. I don't beleive I said anything was "wrong" anywhere.
You've offered nothing as far as evidence or reasoning, except that you
weren't aware of something that you really don't need to be aware of.

What, praytell, was that?
Events deserve to be first class features, they offer semantic value and
are quite commonly used, IMHO.

I'm not sure about "deserve", but certainly there are good arguments for
making them first class, enough that the language designers decided to do
so.
That is sugar to save you time. Its not like the langauge designers are
going out of hteir way to make sure you don't know about the add/remove
accessors.

It really saves me no time, as the collection classes have implemented
events the way they want, and I just use them.
An alternative need not impact me at all.
This is pretty irrelevent. Is your argument really "it works the same, so
why not?"

Then I really have failed, becuase the point was not to make a argument at
all.
The current model has none of htese features because they aren't needed.

Says who? The only time I could have used "event" as a notification source I
could not, because it was lacking more control.
Luckily, one can happily ignore "event" and use the underlying delegates -
so I have on complaints on my ability to acheive my goals with C#.
However, when one can ignore something in a language and do something that
is more general without *much* cost, it's valid to ask if it should be in
the language.

I'm not saying "event" was wrong, but certainly the lack of "event" is not
in the same league as the lack that other languages features would be - a
gaping hole. Basically, "event" is a very useful second "layer" of language
on top of C# -- as C# does not have macros, a meta-programming model, or
other mechanism for "layering", some features from this "base+1" language
layer will natually become part of the language. (Another example includes
Mozart, which has in interesting layered approach to language design, adding
mutability on top of a functional languages with "slots", and then adding OO
on top of this layer.) The use of Reflection.Emit (and the new, lightweight
versions) is another example -- and although done at runtime by necessity,
many uses of Emit are done on information that is all present at
compile-time, such as using reflection to inspect types that were known at
compile-time and to automatically generate concrete implementations for
certain interfaces.
Yet you've yet to come up with any reason why it shouldn't be.

I wasn't trying to say would they *shouldn't* be, I was saying why they
"needn't have been".
You can get by with quite a few more general features alone. You can throw
away properties and define a Property<T> type that has optional get & set
methods. You could do away with iterators, return values, operators,
delegates, and a whole host of other things as well. The point of it all
isn't that you *CAN* get rid of it, the point is that it is easier and\or
permits new scenarios with no costs on any level.

You don't really beleive your own slippery slope argument, so why present
the hyperbole?
Most of your litany of features is either completly impossible to
emulate/replace, or only possible at very great cost.
"event" is not in this category, which is the whole point.
People are split? You are the first person I've ever seen suggest events
don't need to be there.

A quick google on the topic has shown otherwise; although I agree I searched
for what I was looking for -- I'm not saying it's a feeling that most c#
programmers hold. Most people wouldn't give them a second thought - I
decsion that I now highly praise them for :)
They are incredibly simple, distinction from delegate and events excluded,
I really don't get your problem with them. You seem just to think they are
a bad idea.

No, I don't -- they just not necessarily the "best" idea, given your
personal view of optimality. Given the same choice to make, I probably could
have been conviced to include the keywork as well.

m
 
M

Mike

r
Your solution seems to intriduce an unnecessary extra object with
associated allocation and deallocation overhead.

We're only talking about one object that each event the class handles, most
likely allocated statically.
Plus, if you're that worried about object allocation, chances are there's
well enough lower hanging fruit to deal with in any program, probably by
several orders of magnitute.
The thing to remember is that an event is not an object any more than a
property is - it is just a set of methods to access private fields of the
containing class.

Yes, that is how it is implemented currently.

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?
One may well state that in doing this it may be hard to emulate the *exact*
semantics *as they are now*, but that is something I was not try to state --
only that *similar* semantics brought about by this mechanism *would have
been* good enough, and in many ways more general.

At this point, "event" is obviously the way to go if it happens to do what
you want it to do.

m
 
D

Daniel O'Connell [C# MVP]

Sure -- which happens to be the way you implement functionality everywhere
else in the language.
Modifying add/remove behavior is not all that common AFAIKT, and if you
want more control you can just use delegates and your own notification
framework and forego events all-together. In the case of overriding
add/remove behavior, you're "burdening" the control/framework writer, not
the consumer/subscriber.

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.
It's giving false credence to your model since it would only ever come up
with your model. Basic eventing covers it very well without any pointless
complications.
I think somehow we just violently agreed.

Obviously. You seem upset that something exists yet don't seem to mind a
complicated, multiclass solution that would have to follow as strenous a set
of rules and would have to be defined *IN THE SAME PLACE* to be as
effective, unless of course you are quite happy with a myriad of eventing
systems with slightly different semantics.
No. I don't beleive I said anything was "wrong" anywhere.

You seem to imply, deeply, that he current method is wrong...mainly because
you think so. 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.
What, praytell, was that?

Again, no reasons. Are you going to give one?

It really saves me no time, as the collection classes have implemented
events the way they want, and I just use them.
An alternative need not impact me at all.

It saves you no time because you clearly don't actually write them. Have you
ever written a class that *EXPOSES* events or are you just talking strictly
from teh subscriber side here?
Then I really have failed, becuase the point was not to make a argument at
all.

Yes, you have failed. You seem to be just shooting in the dark agaisnt
something you don't like. You've given vitually no reasoning for it, just
complaints about it.
Says who? The only time I could have used "event" as a notification source
I could not, because it was lacking more control.

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.
Luckily, one can happily ignore "event" and use the underlying delegates -
so I have on complaints on my ability to acheive my goals with C#.
However, when one can ignore something in a language and do something that
is more general without *much* cost, it's valid to ask if it should be in
the language.

Sure. But was your general solution of use to anyone but you? Were you even
considering events properly? They are a very simple system that works the
vast majority of the time with absolutly no fuss. You hit one issue, the
only time you felt you need to use events, so they must have been done
wrong?

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'm not saying "event" was wrong, but certainly the lack of "event" is not
in the same league as the lack that other languages features would be - a
gaping hole. Basically, "event" is a very useful second "layer" of
language on top of C# -- as C# does not have macros, a meta-programming
model, or other mechanism for "layering", some features from this "base+1"
language layer will natually become part of the language. (Another example
includes Mozart, which has in interesting layered approach to language
design, adding mutability on top of a functional languages with "slots",
and then adding OO on top of this layer.) The use of Reflection.Emit (and
the new, lightweight versions) is another example -- and although done at
runtime by necessity, many uses of Emit are done on information that is
all present at compile-time, such as using reflection to inspect types
that were known at compile-time and to automatically generate concrete
implementations for certain interfaces.

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.

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. 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 wasn't trying to say would they *shouldn't* be, I was saying why they
"needn't have been".

Sure, you've said why they needn't have been: because you have a different
solution. But that isn't a good answer. There are always other solutions,
unless you can show benefit, you didn't prove anything.
You don't really beleive your own slippery slope argument, so why present
the hyperbole?
Most of your litany of features is either completly impossible to
emulate/replace, or only possible at very great cost.
"event" is not in this category, which is the whole point.

Because I don't know if you actually believe yourself or not either. Almost
everything can be implemented in code, some languages even push it, it is
quite certainly possible to emulate any of these, its all a matter of cost
as you point out. While event is fairly cheap, that doesn't mean that it
shouldn't be moved up into the central language(and, as an argument I never
did make, events are a core part of the concept of a "component" that is a
big piece of the philosophy behind the language.) You have to have either a
technical or philosophical reason for it, merely that it's possible to do
without seems weak to me. Hyperbole, if you will.
A quick google on the topic has shown otherwise; although I agree I
searched for what I was looking for -- I'm not saying it's a feeling that
most c# programmers hold. Most people wouldn't give them a second
thought - I decsion that I now highly praise them for :)

What did you search for exactly? I see a number of articles on the
difference between delegates and events, but nothing else.
No, I don't -- they just not necessarily the "best" idea, given your
personal view of optimality. Given the same choice to make, I probably
could have been conviced to include the keywork as well.

I don't think your method is necessarily the best either. Personally I find
it too complex with no added value.
 
N

Nick Hounsome

[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.
 

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