473,378 Members | 1,541 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.

Events with accessors

I've found information on an explicit way of declaring events, similar
to the way a property is declared:

private EventHandler myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
myEvent += value;
}
}
remove
{
lock (this)
{
myEvent -= value;
}
}
}

Here it is explicitly stated that when handlers are added to the event,
they should be added to the delegate _myEvent, and likewise for removal.
When the event is *raised*, however, I don't understand where this tells
the application to look at _myEvent for the handler(s) to be called.

The add and remove accessors both correspond to the set accessor in a
property declaration, but there isn't anything that corresponds to the
get accessor. The code above seems similar to

private int number;
public int Number
{
set
{
number = value;
}
}

and then expecting that when the statement

int x = Number;

is executed, the application will know to get the required value from
the private field number, when I haven't included a get accessor to make
it so.

What am I missing?
Nov 29 '07 #1
4 1119
Harlan Messinger <hm*******************@comcast.netwrote:
I've found information on an explicit way of declaring events, similar
to the way a property is declared:
<snip>
Here it is explicitly stated that when handlers are added to the event,
they should be added to the delegate _myEvent, and likewise for removal.
When the event is *raised*, however, I don't understand where this tells
the application to look at _myEvent for the handler(s) to be called.
Well, you have to write the code to raise the event yourself. If you
try to call MyEvent() it will fail to compile - you need to call
myEvent().
The add and remove accessors both correspond to the set accessor in a
property declaration, but there isn't anything that corresponds to the
get accessor.
And that's deliberate - clients of the class don't get to find out
what's subscribed - they just get to subscribe and unsubscribe. Only
the class implementing the event knows how to raise it.

See http://pobox.com/~skeet/csharp/events.html for more info.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Nov 29 '07 #2
Jon Skeet [C# MVP] wrote:
Harlan Messinger <hm*******************@comcast.netwrote:
>I've found information on an explicit way of declaring events, similar
to the way a property is declared:

<snip>
>Here it is explicitly stated that when handlers are added to the event,
they should be added to the delegate _myEvent, and likewise for removal.
When the event is *raised*, however, I don't understand where this tells
the application to look at _myEvent for the handler(s) to be called.

Well, you have to write the code to raise the event yourself. If you
try to call MyEvent() it will fail to compile - you need to call
myEvent().
Doh! That's the piece that eluded me. And that, I think, answers the
question that led me to this one: I thought it was rather dumb (though I
suppose there must be some, probably security-related, reason) and
certainly annoying that a "real" event's delegate is private rather than
protected, preventing a derived class from raising an event declared in
a base class. Yes, I know it's a field, therefore ordinarily private,
but this seemed like a good reason to have an exception.
>
>The add and remove accessors both correspond to the set accessor in a
property declaration, but there isn't anything that corresponds to the
get accessor.

And that's deliberate - clients of the class don't get to find out
what's subscribed - they just get to subscribe and unsubscribe. Only
the class implementing the event knows how to raise it.

See http://pobox.com/~skeet/csharp/events.html for more info.
Heh, that redirects to the page I took my code sample from (except that
I removed the initial underscores).

Nov 29 '07 #3
Harlan Messinger <hm*******************@comcast.netwrote:
Well, you have to write the code to raise the event yourself. If you
try to call MyEvent() it will fail to compile - you need to call
myEvent().

Doh! That's the piece that eluded me. And that, I think, answers the
question that led me to this one: I thought it was rather dumb (though I
suppose there must be some, probably security-related, reason) and
certainly annoying that a "real" event's delegate is private rather than
protected, preventing a derived class from raising an event declared in
a base class. Yes, I know it's a field, therefore ordinarily private,
but this seemed like a good reason to have an exception.
Well, you can certainly make it protected if you really want to. It's
just a normal field. Personally, I wouldn't - I'd create a protected
method called OnMyEvent() which raises the event, and keep the detail
private.

Then again, I don't often have events in classes which other classes
derive from - I use inheritance fairly sparingly.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Nov 29 '07 #4
Harlan Messinger <hm*******************@comcast.netwrote:

<snip>
You can
still do that by explicitly providing a protected method which raises
the event... but if it *automatically* made the backing field
protected, with no way of making it private, that would be a really bad
idea.

I had another thought about this. It's similar to the issue of why
separate access levels can't be given to get and set in a property (as
VB6 allows IIRC):

protected set { }
public get { }
You can do that in C# 2/3:

public Foo
{
get { ... }
protected set { ... }
}
It came to me that instead of just *add* and *remove*, events could also
have been given *raise*, with the further option of making add and
remove public while making raise protected where it would be private in
a field-like event. Yes, I realize this is all idle contemplation.
I believe that in CLR terms there *is* an optional raise part, but that
C# and VB.NET don't generate that bit.
A derived class can use the event in exactly the same way as a
different class can - but it can't get at the private implementation,
just as a public or protected property prevents you from getting at the
implementation. There's no disparity here.

I think there is. By attempting to call

MyEvent(source, args);

in a derived class when MyEvent is declared publicly in the base class,
I am no more "getting at" the private implementation than I am "getting
at" the private implementation of a publicly declared property when I
assign to it
Yes you are - because the "raise" isn't encapsulated. Either you'd have
to have direct access to the field, or the event itself would have to
have a raise part. Now, the latter idea has merit - but I wouldn't want
implicit protected access to the field.

The field *is* the private implementation here. Access to that violates
encapsulation.
base.Number = 3;

But I can do the latter--of course I can, that's the whole point of the
"set" accessor--while I can't do the former.
Not without providing your own member to raise the event, no - but
that's easy to do anyway.

<snip>
Now, if you encapsulate that in an protected OnProgressUpdated method,
you've got the "overhead" of declaring a method, but that nullity check
is only implemented once. If you started raising the event directly
from each derived class, you'd have the bloat of that nullity check
everywhere.

Excellent! Though I didn't get around to it, I was going to observe this
myself yesterday afternoon in a follow-up--that it had come to mind that
I needed to be checking for null, and that doing so in just one place
was a good additional factor in favor of wrapping the firing of the
event in a protected method. I did go ahead and revise my app to follow
that approach. Thanks!
Goodo :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Nov 30 '07 #5

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

Similar topics

8
by: Edward Diener | last post by:
Is it possible for a derived class to override a property and/or event of its base class ?
14
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using...
4
by: suresh | last post by:
is there any difference between events and multicast delegates. if so how to differentiate. thanx and regards.
1
by: Manco | last post by:
1. A delegate is a type-safe, object-oriented function pointer. 2. A delegate declartion is C-sharp, f.e., public delegate void MyDelegate(int); defines a MulticastDelgate which contains a...
2
by: COLIN JACK | last post by:
Hi All, I've got a situation where I'm implementing an interface (BaseInterface in example below) and I want to use explicity interface implementation of an event so that I can add type safety. ...
30
by: Burkhard | last post by:
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...
20
by: David Levine | last post by:
I ran into a problem this morning with event accessor methods that appears to be a bug in C# and I am wondering if this a known issue. public event SomeDelegateSignature fooEvent; public event...
3
by: galathaea | last post by:
it surprises me how often engineers confuse states with actions i think this is the fundamental reification behind procedural statemess and this mistake infects a lot of great projects with...
5
by: puzzlecracker | last post by:
I am sort of confused here. Jon Skeet allegedly claims that evens are like properties. To me, on the contrary, they look more like instances of delegates. What's the deal here? Thanks
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
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

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.