What's the use of making an event virtual?

A

Action

does it works like ordinary virtual method??
coz I find that child class can't invoke the event of the parent class.

class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
void abc()
{
this.SomeChanged+=SomeMethod; // ok

if (this.SomeChanged != null) // can't
this.SomeChanged(); // can't
}
}




class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
public override event SomeDelegate SomeChanged; // what's the use of
overriding a parent event?
}

void main()
{
parent childInstance = new childInstance;
childInstance.SomeChanged+=SomeMethod; // it's parent's one or child's
one?
}
 
J

Jon Skeet [C# MVP]

Action said:
does it works like ordinary virtual method??
coz I find that child class can't invoke the event of the parent class.

class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
void abc()
{
this.SomeChanged+=SomeMethod; // ok

if (this.SomeChanged != null) // can't
this.SomeChanged(); // can't
}
}

Presumably that's because you haven't overridden it.
class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
public override event SomeDelegate SomeChanged; // what's the use of
overriding a parent event?
}

You may want to implement the event in a different way. For instance,
if you have several events, only some of which will be subscribed to,
you could keep them in a hashtable to avoid using memory for each
implicit delegate variable declaration. It's rare to do this, IME, but
there *can* be a point of overriding an event.
void main()
{
parent childInstance = new childInstance;
childInstance.SomeChanged+=SomeMethod; // it's parent's one or child's
one?
}

The child's one, I would hope - just as overriding works elsewhere.
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Action,

Don't do that. You'll get nothing but troubles.


class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
void abc()
{
this.SomeChanged+=SomeMethod; // ok

if (this.SomeChanged != null) // can't
this.SomeChanged(); // can't
}
}

Remove the virtual keyword infront of the event declaration and this is the
way to go. The only thing you should do is to declare one protected virtual
OnXXX method that raises the event.

class parent
{
public event SomeDelegate SomeChanged;

protected virtual OnSomeChanged(SomeChangedEventArgs e)
{
if(SomeChanged != null)
SomeChanged(this, e);
}
}


That's it. If you want to raise the event from the child class simply call
OnSomeChanged method

If you want to handle the event in your derived class you have options:
either to hook the event or better to override OnSomeChanged method. If you
choose the latter you can suppress the event by not calling the base
implementation.


Don't ever use the following.
class parent
{
public virtual event SomeDelegate SomeChanged;
}

class child : parent
{
public override event SomeDelegate SomeChanged; // what's the use of
overriding a parent event?
}

void main()
{
parent childInstance = new childInstance;
childInstance.SomeChanged+=SomeMethod; // it's parent's one or child's
one?
}

When you declare an event using the syntax above you declare three things.
One private member of SomeDelegate type (this is what actually keeps the
chain of event handlers and what you test for null). Obviously it cannot be
virtual

And two public accessor methods *add* and *remove* which are actually
declared as virtual.
When you override that event you override the accessors and declare again
the member. So you end up having two different delagate members for the
parent and child classes. Because *add* and *remove* are virtual they always
update the child's memeber so the parent member is always null. If you don's
use virtual method for firing the event base class will never have that
event fired because from its perspective there are never be event handlers.

Actually events has one more accessor which is not supported by C# called
*invoke*. C++ porgrammers use to use it. Thus they use to use virtual
events. However it is always dangerous. So my suggestion is to stick with
OnXXX method and don't use virtual events.
 
D

David Logan

I thought there weren't any "don't do that. You'll get nothing but
trouble" things in this managed coding style :)

David Logan
 
B

babylon

Thank you very much!
Currently, I also use OnXXX to raise events
but I just wonder what's the use of marking an event virtual (since it can
be compiled correctly)

thx
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Unfotunately there are. In the managed word gives you is that you
theoretically cannot crash the system. But nothing saves you to make logical
errors, some of them (the case with the virtual events is I believe) are
hard to track down. Spending even half an hour tryng to figure out why
othewise perfectly written code doesn't work I call trouble. Managed
environment doesn't help you there.
 

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