473,378 Members | 1,422 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Property accessors "add" and "remove" with event properties andEventHandlerList

I have been perusing various blogs and MSDN pages discussing the use
of event properties and the EventHandlerList class. I don't believe
there's anything special about the EventHandlerList class in this
context, in fact some articles from pre-2.0 suggest using any
collection class of your choice. So my questions focus more on the
syntax of event properties provided by the "event" keyword in C#.
(Disclaimer - I am a C++ programmer working on a C# development
project, so I tend to think in C++ and try and translate it in to C#.)

Are the "add" and "remove" properties of an event declaration defined
in a class somewhere, or are they part of the C# language definition?
Are there any other properties? Where are any of these documented?.

I also assume that the compelling reason to use event properties
defined this way is to allow event consumers to use += and -= to
subscribe and unsubscribe to events.

Every C# example I see has a very VB5-centric flavor to it -
specifically, each event must have a unique name defined in the source
code. For instance, here's the code segment from the MSDN article "How
to: Handle Multiple Events Using Event Properties"

// Define the delegate collection.
protected EventHandlerList listEventDelegates = new
EventHandlerList();

// Define a unique key for each event.
static readonly object mouseDownEventKey = new object();
static readonly object mouseUpEventKey = new object();

// Define the MouseDown event property.
public event MouseEventHandler MouseDown {
// Add the input delegate to the collection.
add { listEventDelegates.AddHandler(mouseDownEventKey, value); }
// Remove the input delegate from the collection.
remove { listEventDelegates.RemoveHandler(mouseDownEventKey ,
value); }
}

// Define the MouseUp event property.
public event MouseEventHandler MouseUp {
// Add the input delegate to the collection.
add { listEventDelegates.AddHandler(mouseUpEventKey, value); }
// Remove the input delegate from the collection.
remove { listEventDelegates.RemoveHandler(mouseUpEventKey,
value); }
}

Any time I see code cut-and-pasted like this is a red flag that a
proper object-oriented decomposition of the problem hasn't been
performed. There are two events declared by name (MouseDown and
MouseUp) and yet the code that implements their properties "add" and
"remove" are nearly identical, except for the "key" argument (an
arbitrary static value, to provide a unique key for the
EventHandlerList class).

If the "key" argument could somehow be available to the add and remove
properties, this whole thing could be implemented as a class, and the
events, instead of having to be individually named at compile time,
could be part of a collection of objects of that class. However, the
"add" and "remove" properties seem to be a "hardcoded" notion in the
C# language, with the keyword "value" the only argument available to
the implementation of those properties (in this case, "value" is of
type Delegate). Am I misunderstanding this?

I have also read posts here that suggest "event" is syntactic sugar
such that the C# compiler will automatically generate the property
accessor functions, so that clients can use the += and -=.

If I wanted to ditch this notion that every event has to have a name
defined at compile time, I can think of how to implement such a class
hierarchy. However, I'm not sure if can override the += and -=
operators in my homegrown event properties implementation - would this
be possible?

Thanks
Jun 27 '08 #1
4 9811
FullBandwidth <Fu***********@comcast.netwrote:
I have been perusing various blogs and MSDN pages discussing the use
of event properties and the EventHandlerList class. I don't believe
there's anything special about the EventHandlerList class in this
context, in fact some articles from pre-2.0 suggest using any
collection class of your choice. So my questions focus more on the
syntax of event properties provided by the "event" keyword in C#.
(Disclaimer - I am a C++ programmer working on a C# development
project, so I tend to think in C++ and try and translate it in to C#.)

Are the "add" and "remove" properties of an event declaration defined
in a class somewhere, or are they part of the C# language definition?
They're part of the C# language specification, and also the CLI spec.
Are there any other properties? Where are any of these documented?.
They aren't properties. They're operations on the event. They're
similar to the "get" and "set" part of real properties, with the
difference that you can't declare an event with an "add" but not a
"remove" (or vice versa).

IIRC, the CLI spec includes another associated method: "raise" which C#
neither generates nor refers to.
I also assume that the compelling reason to use event properties
defined this way is to allow event consumers to use += and -= to
subscribe and unsubscribe to events.
Yes, it's encapsulation. It allows the class to advertise an event in a
subscribe/unsubscribe manner, but internally keep it in whatever
implementation it wants.
Every C# example I see has a very VB5-centric flavor to it -
specifically, each event must have a unique name defined in the source
code.
I don't see why that's VB5-centric. If each event doesn't have a unique
name, how could it be resolved at compile-time in a statically typed
manner?
For instance, here's the code segment from the MSDN article "How
to: Handle Multiple Events Using Event Properties"
<snip>
Any time I see code cut-and-pasted like this is a red flag that a
proper object-oriented decomposition of the problem hasn't been
performed. There are two events declared by name (MouseDown and
MouseUp) and yet the code that implements their properties "add" and
"remove" are nearly identical, except for the "key" argument (an
arbitrary static value, to provide a unique key for the
EventHandlerList class).
Do you think there's a "red flag" every time you see a property
declared which just reads/writes from/to a variable? That's just cut-
and-paste code using different variables each time, too. It's not like
there's significant logic being duplicated.
If the "key" argument could somehow be available to the add and remove
properties, this whole thing could be implemented as a class, and the
events, instead of having to be individually named at compile time,
could be part of a collection of objects of that class. However, the
"add" and "remove" properties seem to be a "hardcoded" notion in the
C# language, with the keyword "value" the only argument available to
the implementation of those properties (in this case, "value" is of
type Delegate). Am I misunderstanding this?
I think you're misunderstanding the real nature of an event. An event
is like a property - it has two associated methods with it, for
callers. It's not that add and remove are properties *of* the event.
They're just methods associated with it.
I have also read posts here that suggest "event" is syntactic sugar
such that the C# compiler will automatically generate the property
accessor functions, so that clients can use the += and -=.
The compiler will automatically generate the add/remove if you use a
field-like event, which is where you just write something like:

public event EventHandler Click;

That will create an event called Click and a hidden variable of type
EventHandler. The variable is private - whenever you refer to "Click"
from within the class, that refers to the variable; whenever you refer
to "Click" from outside the class, that refers to the event. The
add/remove which are automatically generated are effectively:

add
{
lock(this)
{
compiler_generated_click_variable += value;
}
}
remove
{
lock(this)
{
compiler_generated_click_variable -= value;
}
}
If I wanted to ditch this notion that every event has to have a name
defined at compile time, I can think of how to implement such a class
hierarchy. However, I'm not sure if can override the += and -=
operators in my homegrown event properties implementation - would this
be possible?
If you didn't have names defined at compile-time, += and -= don't make
any sense anyway as far as I can see.

You could of course write two methods:

public void AddHandler(string eventName, EventHandler handler)
public void RemoveHandler(string eventName, EventHandler handler)

But you'd lose all the compile-time safety, relying on magic names
instead. (You could use an enum instead, of course, but it's still not
ideal.)

Personally I'd stick with the idiomatic .NET solution. If other people
use your API, they're unlikely to want to learn another eventing
mechanism.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #2
There is another reason to stick with the trend; it is what other
framework code expects [your code isn't the only thing that attaches
to events].

For example, data-binding supports 2 patterns; one of these is the
"property Foo, event FooChanged" pair, which PropertyDescriptor will
recognise and expose via SupportsChangeEvents, AddValueChanged and
RemoveValueChanged. This will only work if your event uses the regular
event pattern. Note, however, then the encapsulated implementation is
not an issue - inside the event it could use a delegate field (either
explicit or implicit from the abbreviated event syntax), or it could
use EventHandlerList, etc.

Another example here would be the IDE; the IDE has fairly good support
for events. With an alternative strategy, some of this would
undoubtably be lost.

Marc
Jun 27 '08 #3
Guys, thanks for the comments, I am grateful for your insights. A
couple of go-backs, if you're willing to follow up:

>
Every C# example I see has a very VB5-centric flavor to it -
specifically, eacheventmust have a unique name defined in the source
code.

I don't see why that's VB5-centric. If eacheventdoesn't have a unique
name, how could it be resolved at compile-time in a statically typed
manner?
"VB5-centric" meaning "resistant to implementation as a factory (or
other pattern)," I guess is what I was trying to say. It seems like
VB4, VB5, VB6 etc. crawled along the path towards Booch-style OO that
Smalltalk, C++, Java, and C# always had built-in. So it was an
inflammatory dig, to some extent, but I didn't figure there'd be too
many VB apologists on this newsgroup ;)

Maybe I haven't thought through it enough (or am still too mired in
the C/C++ notion of collections of function pointers), but I still
don't see why event delcarations need to be available at compile-time
by individual names, versus a collection of appropriately (statically)
typed objects that could be manipulated at run time.
Any time I see code cut-and-pasted like this is a red flag that a
proper object-oriented decomposition of the problem hasn't been
performed. There are two events declared by name (MouseDown and
MouseUp) and yet the code that implements theirproperties"add" and
"remove" are nearly identical, except for the "key" argument (an
arbitrary static value, to provide a unique key for the
EventHandlerList class).

Do you think there's a "red flag" every time you see a property
declared which just reads/writes from/to a variable? That's just cut-
and-paste code using different variables each time, too. It's not like
there's significant logic being duplicated.
Y'know, now that you mention it... but that's a topic for another
thread...
If the "key" argument could somehow be available to the add and remove
properties, this whole thing could be implemented as a class, and the
events, instead of having to be individually named at compile time,
could be part of a collection of objects of that class. However, the
"add" and "remove"propertiesseem to be a "hardcoded" notion in the
C# language, with the keyword "value" the only argument available to
the implementation of thoseproperties(in this case, "value" is of
type Delegate). Am I misunderstanding this?

I think you're misunderstanding the real nature of anevent. Anevent
is like a property - it has two associated methods with it, for
callers. It's not that add and remove areproperties*of* theevent.
They're just methods associated with it.
Meaning, the real nature of an event as currently implemented in C#.
Maybe not the implementation I would have preferred, but at least I
understand now what that implementation is.

If I wanted to ditch this notion that everyeventhas to have a name
defined at compile time, I can think of how to implement such a class
hierarchy. However, I'm not sure if can override the += and -=
operators in my homegrowneventpropertiesimplementation - would this
be possible?

If you didn't have names defined at compile-time, += and -= don't make
any sense anyway as far as I can see.
The RHS of such an expression would be an element from the collection
of delegates - indexed by a unique key, something like what you've
expressed below:
>
You could of course write two methods:

public void AddHandler(string eventName, EventHandler handler)
public void RemoveHandler(string eventName, EventHandler handler)

But you'd lose all the compile-time safety, relying on magic names
instead. (You could use an enum instead, of course, but it's still not
ideal.)
Actually the motive behind these questions is that I am trying to brew
up a more complete "event properties" example, one that includes both
the Observer pattern and the Chain of Command pattern. The comments
you guys provided have gotten me closer to that; I hope to post it
here and get some critiques on it. The example I have now uses
typeof() and a class hierarchy (vs. magic names or enums). I realize
that doesn't make much sense out of context, but maybe it will when I
post the example.
>
Personally I'd stick with the idiomatic .NET solution. If other people
use your API, they're unlikely to want to learn another eventing
mechanism.
>There is another reason to stick with the trend; it is what other
framework code expects [your code isn't the only thing that attaches
to events].
Quite true - really what I was trying to find out exactly what the
extent of that idiom is. That way, this thorough example I'm trying to
come up with is recognizeable as consistent with the idiom.
Thanks again.
Jun 27 '08 #4
On Jun 20, 12:49*pm, FullBandwidth <FullBandwi...@comcast.netwrote:
I don't see why that's VB5-centric. If eacheventdoesn't have a unique
name, how could it be resolved at compile-time in a statically typed
manner?

"VB5-centric" meaning "resistant to implementation as a factory (or
other pattern)," I guess is what I was trying to say. It seems like
VB4, VB5, VB6 etc. crawled along the path towards Booch-style OO that
Smalltalk, C++, Java, and C# always had built-in. So it was an
inflammatory dig, to some extent, but I didn't figure there'd be too
many VB apologists on this newsgroup ;)

Maybe I haven't thought through it enough (or am still too mired in
the C/C++ notion of collections of function pointers), but I still
don't see why event delcarations need to be available at compile-time
by individual names, versus a collection of appropriately (statically)
typed objects that could be manipulated at run time.
How would you wish to subscribe to, say, the "Click" event of
something instead of the "DoubleClick" event? You could have a
collection with some sort of enum key - but then you'd need to
associate the type of each event with its key as well. While this
could be done with sufficient language support I don't think it would
add much over the current way of doing things.

It's also helpful to have the set of events associated with a type
discoverable via reflection - there would need to be support for this
in some form or other for designers etc.
I think you're misunderstanding the real nature of anevent. Anevent
is like a property - it has two associated methods with it, for
callers. It's not that add and remove areproperties*of* theevent.
They're just methods associated with it.

Meaning, the real nature of an event as currently implemented in C#.
Maybe not the implementation I would have preferred, but at least I
understand now what that implementation is.
No, it's not C# - it's .NET. An event in .NET has those aspects of
metadata (and another optional one for raising the event, IIRC, which
C# ignores). You're right that it's technology-specific terminology,
but it's not C#-specific.
If I wanted to ditch this notion that everyeventhas to have a name
defined at compile time, I can think of how to implement such a class
hierarchy. However, I'm not sure if can override the += and -=
operators in my homegrowneventpropertiesimplementation - would this
be possible?
If you didn't have names defined at compile-time, += and -= don't make
any sense anyway as far as I can see.

The RHS of such an expression would be an element from the collection
of delegates - indexed by a unique key, something like what you've
expressed below:
Okay, so we'd need different language features to safely have the keys
and associated types. We'd also end up defining a new collection of
event keys (probably a new type) every time we wanted to implement an
event. The common implementation of events isn't to use EventList to
start with, unless you've got a lot of events which are likely to be
sparsely populated.

While I can see merit in avoiding the repetition, I think the current
idiom works pretty well and the *practical* issues with the repetition
are minimal in my experience.
But you'd lose all the compile-time safety, relying on magic names
instead. (You could use an enum instead, of course, but it's still not
ideal.)

Actually the motive behind these questions is that I am trying to brew
up a more complete "event properties" example, one that includes both
the Observer pattern and the Chain of Command pattern. The comments
you guys provided have gotten me closer to that; I hope to post it
here and get some critiques on it. The example I have now uses
typeof() and a class hierarchy (vs. magic names or enums). I realize
that doesn't make much sense out of context, but maybe it will when I
post the example.
Using typeof() and class hierarchies doesn't immediately sound nice, I
have to say. There are alternatives for "smart enums", although they
don't have much language support. When I've seen your code I may be
able to suggest some of them :)
Personally I'd stick with the idiomatic .NET solution. If other people
use your API, they're unlikely to want to learn another eventing
mechanism.
There is another reason to stick with the trend; it is what other
framework code expects [your code isn't the only thing that attaches
to events].

Quite true - really what I was trying to find out exactly what the
extent of that idiom is. That way, this thorough example I'm trying to
come up with is recognizeable as consistent with the idiom.

Thanks again.
No problem. I'll look forward to seeing your code, although I'm still
somewhat doubtful that I'll be won over ;)

Jon
Jun 27 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: George Copeland | last post by:
This is a request for help fixing a SQL Server 2000/ADO problem on Windows XP. I would appreciate any useful assistance. PROBLEM: SQL Server access on my machine fails as follows: 1. All of...
9
by: Paul | last post by:
Hi, VB.NET is saying the file I am creating is in use by another process and won't complete its task of moving the file to the specified destination folder. Here is my code (the main bit...
2
by: NTE | last post by:
Access 2000 and 2003. I have made a custom toolbar to allow users to filter by form, etc. The only things I want to appear on that toolbar are the 3 buttons to control filtering. At the right...
1
by: Dan Bass | last post by:
I'm looking to develop a listbox with in-place editing where as each item is selected, it grows to fit in all the text boxes. When the item is deselected, it shrinks back to its original size. The...
5
by: chris_doran | last post by:
/COMMENT has been removed from the linker that comes with VS2005, and use in source code of: #pragma comment(exestr, "this is a string") gives the message: warning LNK4224: /COMMENT is no...
4
by: lesperancer | last post by:
it looks like this will save many versions of a relationship window, but based on the fact that the same tables are displayed in the relationship window and it will restore versions of what was...
0
by: zhif | last post by:
I tried to load data into MySQL The command I used is as below, load data local infile 'c:/tmp_0124/COL_LIQ_RPT.del' into table COL_LIQ_RPT fields terminated by ';' lines terminated by '\n' ...
2
by: driveman | last post by:
Hello, I have existing code working perfectly, which can : -clone existing datas (title, textarea, link-to-picture) contained in xml file, and : -delete datas. I looking for a javascript code...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.