By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,444 Members | 3,110 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,444 IT Pros & Developers. It's quick & easy.

Virtual Override Events Inheritance

P: n/a
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 events since I never saw it used anywhere in MSDN documentation/samples?! Or it will just break when I upgrade to .NET Framework 2.x in the coming years

namespace MyNamespac

public delegate void MyDel()

public class MyBase

public virtual event MyDel MyEvent
public void MyMethod2(

MyEvent()

public class MyDerived : MyBas

// Override base class event so that it can
// be raise from child (here!
public override event MyDel MyEvent

public void MyMethod(
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base clas
MyEvent()


Thank
JPRoo

Nov 15 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
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 events since I
never saw it used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the coming years?


It's supported and documented alright. See

http://msdn.microsoft.com/library/en...pspec_10_7.asp
http://msdn.microsoft.com/library/en...pec_10_7_4.asp

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Nov 15 '05 #2

P: n/a
I've never had the occasion to use that syntax, but the
ECMA C# spec says that virtual events should be supported
in the same way that virtual methods are, so I think
you're ok on that front. As to future support, does
anyone know where a 2.x spec might be that could change
that?

JER
-----Original Message-----
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 events since I never saw it
used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the
coming years?
namespace MyNamespace
{
public delegate void MyDel();

public class MyBase
{
public virtual event MyDel MyEvent;
public void MyMethod2()
{
MyEvent();
}
}

public class MyDerived : MyBase
{
// Override base class event so that it can // be raise from child (here!)
public override event MyDel MyEvent;

public void MyMethod()
{ // Raise event. Without the virtual/override keywords, // child classes are not allowed to raise events declared // in their base class
MyEvent();
}
}
}

Thanks
JPRoot

.

Nov 15 '05 #3

P: n/a
Do you mean the OnEventBlah method call which is defined as

protected virtual OnEvenetMethodHere(blah)
{
}

?
"Jerry Negrelli" <je************@nospamdatascientific.com> wrote in message
news:03****************************@phx.gbl...
I've never had the occasion to use that syntax, but the
ECMA C# spec says that virtual events should be supported
in the same way that virtual methods are, so I think
you're ok on that front. As to future support, does
anyone know where a 2.x spec might be that could change
that?

JER
-----Original Message-----
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 events since I never saw it
used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the
coming years?

namespace MyNamespace
{
public delegate void MyDel();

public class MyBase
{
public virtual event MyDel MyEvent;
public void MyMethod2()
{
MyEvent();
}
}

public class MyDerived : MyBase
{
// Override base class event so that it

can
// be raise from child (here!)
public override event MyDel MyEvent;

public void MyMethod()
{ // Raise event. Without the

virtual/override keywords,
// child classes are not allowed

to raise events declared
// in their base class
MyEvent();
}
}
}

Thanks
JPRoot

.

Nov 15 '05 #4

P: n/a
Oh wait, the actual event, why would you need to do this?
"Alvin Pruney" <.> wrote in message
news:ei*************@tk2msftngp13.phx.gbl...
Do you mean the OnEventBlah method call which is defined as

protected virtual OnEvenetMethodHere(blah)
{
}

?
"Jerry Negrelli" <je************@nospamdatascientific.com> wrote in message news:03****************************@phx.gbl...
I've never had the occasion to use that syntax, but the
ECMA C# spec says that virtual events should be supported
in the same way that virtual methods are, so I think
you're ok on that front. As to future support, does
anyone know where a 2.x spec might be that could change
that?

JER
-----Original Message-----
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 events since I never saw it
used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the
coming years?

namespace MyNamespace
{
public delegate void MyDel();

public class MyBase
{
public virtual event MyDel MyEvent;
public void MyMethod2()
{
MyEvent();
}
}

public class MyDerived : MyBase
{
// Override base class event so that it

can
// be raise from child (here!)
public override event MyDel MyEvent;

public void MyMethod()
{ // Raise event. Without the

virtual/override keywords,
// child classes are not allowed

to raise events declared
// in their base class
MyEvent();
}
}
}

Thanks
JPRoot

.


Nov 15 '05 #5

P: n/a
Is the ECMA C# specs actually final or draft?

Has any other part submitted draft ammendments , after all surely anybody
could, right?

"Alvin Pruney" <.> wrote in message
news:ej**************@TK2MSFTNGP10.phx.gbl...
Oh wait, the actual event, why would you need to do this?
"Alvin Pruney" <.> wrote in message
news:ei*************@tk2msftngp13.phx.gbl...
Do you mean the OnEventBlah method call which is defined as

protected virtual OnEvenetMethodHere(blah)
{
}

?
"Jerry Negrelli" <je************@nospamdatascientific.com> wrote in

message
news:03****************************@phx.gbl...
I've never had the occasion to use that syntax, but the
ECMA C# spec says that virtual events should be supported
in the same way that virtual methods are, so I think
you're ok on that front. As to future support, does
anyone know where a 2.x spec might be that could change
that?

JER

>-----Original Message-----
>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 events since I never saw it
used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the
coming years?
>
>namespace MyNamespace
>{
> public delegate void MyDel();
>
> public class MyBase
> {
> public virtual event MyDel MyEvent;
> public void MyMethod2()
> {
> MyEvent();
> }
> }
>
> public class MyDerived : MyBase
> {
> // Override base class event so that it
can
> // be raise from child (here!)
> public override event MyDel MyEvent;
>
> public void MyMethod()
> { // Raise event. Without the
virtual/override keywords,
> // child classes are not allowed
to raise events declared
> // in their base class
> MyEvent();
> }
> }
>}
>
>Thanks
>JPRoot
>
>.
>



Nov 15 '05 #6

P: n/a
Here's a link to the most recent version of the spec:

http://www.ecma-
international.org/publications/standards/Ecma-334.htm

and everything's a work in progress, right? ;)

JER
-----Original Message-----
Is the ECMA C# specs actually final or draft?

Has any other part submitted draft ammendments , after all surely anybodycould, right?

"Alvin Pruney" <.> wrote in message
news:ej**************@TK2MSFTNGP10.phx.gbl...
Oh wait, the actual event, why would you need to do this?

"Alvin Pruney" <.> wrote in message
news:ei*************@tk2msftngp13.phx.gbl...
> Do you mean the OnEventBlah method call which is defined as >
> protected virtual OnEvenetMethodHere(blah)
> {
> }
>
> ?
>
>
> "Jerry Negrelli" <je************@nospamdatascientific.com> wrote in
message
> news:03****************************@phx.gbl...
> > I've never had the occasion to use that syntax,

but the > > ECMA C# spec says that virtual events should be supported > > in the same way that virtual methods are, so I think > > you're ok on that front. As to future support, does > > anyone know where a 2.x spec might be that could change > > that?
> >
> > JER
> >
> > >-----Original Message-----
> > >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 events since I never saw it > > used anywhere in MSDN documentation/samples?! Or it will > > just break when I upgrade to .NET Framework 2.x in the > > coming years?
> > >
> > >namespace MyNamespace
> > >{
> > > public delegate void MyDel();
> > >
> > > public class MyBase
> > > {
> > > public virtual event MyDel MyEvent;
> > > public void MyMethod2()
> > > {
> > > MyEvent();
> > > }
> > > }
> > >
> > > public class MyDerived : MyBase
> > > {
> > > // Override base class event so that it
> > can
> > > // be raise from child (here!)
> > > public override event MyDel MyEvent;
> > >
> > > public void MyMethod()
> > > { // Raise event. Without the
> > virtual/override keywords,
> > > // child classes are not allowed
> > to raise events declared
> > > // in their base class
> > > MyEvent();
> > > }
> > > }
> > >}
> > >
> > >Thanks
> > >JPRoot
> > >
> > >.
> > >
>
>


.

Nov 15 '05 #7

P: n/a
100
Hi JPRoot,

IMHO this is indeed very strange way to use base class's events. And beside
I find it strange it is wrong or at least error prone.

You have to check the event for null before fire it because you can't know
if you have handlers registered for that event:
if(MyEvent != null) MyEvent();

But this is not the bigest flaw.

When you define an event as virtual actually you define its accessors (add
and remove) as virtual, but each class in the hierarchy will have its own
field of type *delegate void MyDel()* to hold the handlers

What does it means? Let me provide a new example.

public delegate void MyDel();

class Foo
{
public virtual MyDel MyEvent;
public FooRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

class Bar: Foo
{
public override MyDel MyEvent;
public BarRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

Now let we have the following code snippet

Foo foo = new Bar();
foo.MyEvent += new MyDel(foo_MyEvent);
Bar bar = (Bar) foo; //we can do that because the object is of type Bar.

bar.BarRaiseMyEvent(); //Everything is just perfect the event fires
bar.FooRaiseMyEvent(); // Bar inherits this method from Foo, but no event
fires.

Which means that no methods form the base class can fire the event. Imagine
if you have more classes in the hierarchy....

Why is this happen?
Because doing
foo.MyEvent += new MyDel(foo_MyEvent);
we call MeEvent's *add* accessor polymorphically and the one decalred in Bar
will be called. It will add the handler to the delegate chain in Bar's field
of type MyDel.
Now when BarRaiseMyEvent calles MyEvent() it uses Bar's delegate field,
which has something inside.
FooRaiseMyEvent., though, uses Foo's delegate field which has nothing inside
and no event is fired.
Access to Fields cannot be polymorphical.

To use events declared in the base class use the design pattern used
throughout the framework (OnXXX methods).
I believe it is described somewhere in MSDN but I don't remember where.
Try to look at
ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconprovidingeventfunctional
ity.htm
HTH
B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:0A**********************************@microsof t.com...
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 events since I never saw it
used anywhere in MSDN documentation/samples?! Or it will just break when I
upgrade to .NET Framework 2.x in the coming years?
namespace MyNamespace
{
public delegate void MyDel();

public class MyBase
{
public virtual event MyDel MyEvent;
public void MyMethod2()
{
MyEvent();
}
}

public class MyDerived : MyBase
{
// Override base class event so that it can
// be raise from child (here!)
public override event MyDel MyEvent;

public void MyMethod()
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base class
MyEvent();
}
}
}

Thanks
JPRoot

Nov 15 '05 #8

P: n/a
That's a good new since having it documented makes it a little more difficult for MS to stop supporting it..

Second question then..
Seems by trial and error that the virtual keyword on the event "virtualize" only the Add and Remove accessor and not the Raise

Taking for exemple the code that I have posted previously, it appears that when raising the event in MyBase::MyMethod2() uses the invocation list of the base class instance MyBase::MyEvent and when raising the event MyDerived::MyMethod() it uses the invocation list of the derived class instance. That defeats the purpose of "virtual" where the base class doesn't use the specialized implementation?!

So if I register to the event, using a pointer to the base class or the child, it always get registered in the derived class invocation list (so Add/Remove are really virtual). If I call MyMethod I receive the event, if I call MyMethod2, I receive an exception stating that the event invocation list is empty !!

Any thoughts

Than
JPRoo
----- Mattias Sjögren wrote: ----

I use the following syntax to have events inherited from base to chil
classes which works nicely (virtual and override keyword on events)
But I am wondering if it is a "supported" way of using events since
never saw it used anywhere in MSDN documentation/samples?! Or it wil
just break when I upgrade to .NET Framework 2.x in the coming years


It's supported and documented alright. Se

http://msdn.microsoft.com/library/en...rpspec_10_7.as
http://msdn.microsoft.com/library/en...spec_10_7_4.as

Mattia

--
Mattias Sjögren [MVP] mattias @ mvps.or
http://www.msjogren.net/dotnet
Please reply only to the newsgroup

Nov 15 '05 #9

P: n/a

Hi,

I have reviewed your post. I will do some research for you.
I will reply to you ASAP.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Thread-Topic: Virtual Override Events Inheritance
| thread-index: AcOqNrWCuoOYF9SrS3WjsXs6rYhgEQ==
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| From: =?Utf-8?B?SlBSb290?= <JP****@hotmail.com>
| References: <0A**********************************@microsoft.co m>
<##**************@TK2MSFTNGP12.phx.gbl>
| Subject: Re: Virtual Override Events Inheritance
| Date: Thu, 13 Nov 2003 14:37:24 -0800
| Lines: 39
| Message-ID: <39**********************************@microsoft.co m>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 8bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: TK2MSFTCMTY1 10.40.1.180
| Path: cpmsftngxa06.phx.gbl!cpmsftngxa10.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:199196
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| That's a good new since having it documented makes it a little more
difficult for MS to stop supporting it...

Second question then...
Seems by trial and error that the virtual keyword on the event "virtualize"
only the Add and Remove accessor and not the Raise.

Taking for exemple the code that I have posted previously, it appears that
when raising the event in MyBase::MyMethod2() uses the invocation list of
the base class instance MyBase::MyEvent and when raising the event
MyDerived::MyMethod() it uses the invocation list of the derived class
instance. That defeats the purpose of "virtual" where the base class
doesn't use the specialized implementation?!

So if I register to the event, using a pointer to the base class or the
child, it always get registered in the derived class invocation list (so
Add/Remove are really virtual). If I call MyMethod I receive the event, if
I call MyMethod2, I receive an exception stating that the event invocation
list is empty !!!

Any thoughts?

Thank
JPRoot

----- Mattias Sjögren wrote: -----

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 events since I
never saw it used anywhere in MSDN documentation/samples?! Or it will
just break when I upgrade to .NET Framework 2.x in the coming years?


It's supported and documented alright. See
http://msdn.microsoft.com/library/en...pspec_10_7.asp

http://msdn.microsoft.com/library/en...pspec_10_7_4.a
sp

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

|

Nov 15 '05 #10

P: n/a
100
Hi JPRoot,
Ok, VC++ defines 3 accessors for events (for adding, removing and raising
the event).
*add* and *remove* accessors has the visibility which is specified for the
event when it is decalred. *Rise* accesor is almost always protected except
when the event is private then and *raise* accessor is private.

What does it mean?
That means that you don't have to do anything in C++ to inherit the base
event. So your code can be transformed to

namespace MyNamespace
{
public __delegate void MyDel();
public __gc class MyBase
{
public:
__event MyDel* MyEvent;

public:
void MyMethod2()
{
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{

public:
void MyMethod()
{
//This will raise the base class' event because raise_MyEvent
method is protected
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,
MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();

MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}

And this will work just perfectly.

This is not the case of C#, though. C# compiler doesn't generate *raise*
accessors for events and it inlines calls delegate's Invoke method whenever
it finds language constuction like DelegateMemberName(....).
For the sme line VC++ will generate call to raise_DelegateMemberName(....)
method.
Which means that VC++ programs cannot use classes written in C# because they
don't have raise_XXX methods defined as well as if you write the class
hierarchy as in the VC++ examples we discuss C# program will be able to use
the parent event only if the C# programmer knows about those raise_XXX
methods.

Who is wrong in this case. I'm really really confused.
If we look in CLI specification (Part I - Architecture) we can find:
Per 8.11.4 Event Definitions
The CTS supports events in precisely the same way that it supports
properties (see clause 8.11.3). The
conventional methods, however, are different and include means for
subscribing and unsubscribing to events as
well as for firing the event.

-------
C# doesn't generate method for *firing* the event.

Per 10.4 Naming Patterns
See also Partition V. 30
While the CTS does not dictate the naming of properties or events, the CLS
does specify a pattern to be
observed.
For Events:
An individual event is created by choosing or defining a delegate type that
is used to signal the event. Then,
three methods are created with names based on the name of the event and with
a fixed signature. For the
examples below we define an event named Click that uses a delegate type
named EventHandler.
EventAdd, used to add a handler for an event
Pattern: void add_<EventName> (<DelegateType> handler)
Example: void add_Click (EventHandler handler);
EventRemove, used to remove a handler for an event
Pattern: void remove_<EventName> (<DelegateType> handler)
Example: void remove_Click (EventHandler handler);
EventRaise, used to signal that an event has occurred
Pattern: void family raise_<EventName> (Event e)
------
C# creates only two names.
Per 8.10.3 Property and Event Inheritance
.....
The source compiler shall generate CIL that directly accesses the methods
named by the events and properties, not the events or properties themselves.

------
C# compiler doesn't use the method decalred for raising the event

And I finaly got lost in my confusion when I saw that no class of the
framework has raise_XXX method.

I have to confess that I haven't read the specs carefully so I might
misunderstood something.
Can anybody explain what CLI specification states and why only VC++
generates and uses *raise* methods?
Neither C# nor VB.NET do that

B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:B8**********************************@microsof t.com...
100,
You are 100% right.

The point I am trying to make is that the Add and Remove are made virtual when you put the virtual keyword besides the event keyword but not the Raise
which I see as a bug(or lack of completeness of the feature) since in
VC++.NET Managed when you put the virtual keyword besides an __event not
only the Add and Remove becomes virtual but also the Raise method, which
makes complete sence!!
Other feature that C# lacks is a way to define the Raise method like you can do in VC++.NET Managed.
Here's the exact same snippet I first posted but in VC++.NET Managed where event "virtualization" really works!! Also, having it this way, makes it
useless to have OnXXX pattern... or at least less useful :)
#using <mscorlib.dll>
#include <tchar.h>

using namespace System;

namespace MyNamespace
{
__delegate void MyDel();
public __gc class MyBase
{
public:
virtual __event MyDel* MyEvent;

public:
void MyMethod2()
{ // this should call child class event if overriden
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{
protected:
__event MyDel* m_myEventInvokeList;
public:
virtual __event void add_MyEvent(MyDel* d)
{
m_myEventInvokeList += d;
}

virtual __event void remove_MyEvent(MyDel* d)
{
m_myEventInvokeList -= d;
}

protected:
virtual __event void raise_MyEvent()
{
__raise m_myEventInvokeList();
}

public:

void MyMethod()
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base class
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0, MyNamespace::EventReceiver::MyEventHandler ); aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();
MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}
----- 100 wrote: -----

Hi JPRoot,

IMHO this is indeed very strange way to use base class's events. And beside I find it strange it is wrong or at least error prone.

You have to check the event for null before fire it because you can't know if you have handlers registered for that event:
if(MyEvent != null) MyEvent();

But this is not the bigest flaw.

When you define an event as virtual actually you define its accessors (add and remove) as virtual, but each class in the hierarchy will have its own field of type *delegate void MyDel()* to hold the handlers

What does it means? Let me provide a new example.

public delegate void MyDel();

class Foo
{
public virtual MyDel MyEvent;
public FooRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

class Bar: Foo
{
public override MyDel MyEvent;
public BarRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

Now let we have the following code snippet

Foo foo = new Bar();
foo.MyEvent += new MyDel(foo_MyEvent);
Bar bar = (Bar) foo; //we can do that because the object is of type Bar.
bar.BarRaiseMyEvent(); //Everything is just perfect the event fires
bar.FooRaiseMyEvent(); // Bar inherits this method from Foo, but no event fires.

Which means that no methods form the base class can fire the event. Imagine if you have more classes in the hierarchy....

Why is this happen?
Because doing
foo.MyEvent += new MyDel(foo_MyEvent);
we call MeEvent's *add* accessor polymorphically and the one decalred in Bar will be called. It will add the handler to the delegate chain in Bar's field of type MyDel.
Now when BarRaiseMyEvent calles MyEvent() it uses Bar's delegate field, which has something inside.
FooRaiseMyEvent., though, uses Foo's delegate field which has nothing inside and no event is fired.
Access to Fields cannot be polymorphical.

To use events declared in the base class use the design pattern used
throughout the framework (OnXXX methods).
I believe it is described somewhere in MSDN but I don't remember where. Try to look at
ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconprovidingeventfunctional ity.htm
HTH
B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:0A**********************************@microsof t.com...
> 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 events since I never saw it used anywhere in MSDN documentation/samples?! Or it will just break when I upgrade to .NET Framework 2.x in the coming years? >> namespace MyNamespace

> {
> public delegate void MyDel();
>> public class MyBase

> {
> public virtual event MyDel MyEvent;
> public void MyMethod2()
> {
> MyEvent();
> }
> }
>> public class MyDerived : MyBase

> {
> // Override base class event so that it can
> // be raise from child (here!)
> public override event MyDel MyEvent;
>> public void MyMethod()

> { // Raise event. Without the virtual/override keywords,
> // child classes are not allowed to raise events declared
> // in their base class
> MyEvent();
> }
> }
> }
>> Thanks

> JPRoot
>

Nov 15 '05 #11

P: n/a
100
Hi JPRoot,
I made a post in other thread's branch. Anyway, I just want ot make a
comment here. C# doesn't use *raise* accessors. Which makes declaring an
event as virtual really really usless, except in the cases with event
declared as part of an interface. In the latter case event is abstract so
virtual. As I see you come from managed VC++ where to have virtual events
really make sense.

B\rgds
100

"JPRoot" <JP****@hotmail.com> wrote in message
news:39**********************************@microsof t.com...
That's a good new since having it documented makes it a little more difficult for MS to stop supporting it...
Second question then...
Seems by trial and error that the virtual keyword on the event "virtualize" only the Add and Remove accessor and not the Raise.
Taking for exemple the code that I have posted previously, it appears that when raising the event in MyBase::MyMethod2() uses the invocation list of
the base class instance MyBase::MyEvent and when raising the event
MyDerived::MyMethod() it uses the invocation list of the derived class
instance. That defeats the purpose of "virtual" where the base class doesn't
use the specialized implementation?!
So if I register to the event, using a pointer to the base class or the child, it always get registered in the derived class invocation list (so
Add/Remove are really virtual). If I call MyMethod I receive the event, if I
call MyMethod2, I receive an exception stating that the event invocation
list is empty !!!
Any thoughts?

Thank
JPRoot

----- Mattias Sjögren wrote: -----

>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 events since I >never saw it used anywhere in MSDN documentation/samples?! Or it will >just break when I upgrade to .NET Framework 2.x in the coming years?
It's supported and documented alright. See

http://msdn.microsoft.com/library/en...pspec_10_7.asp http://msdn.microsoft.com/library/en...pec_10_7_4.asp
Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

Nov 15 '05 #12

P: n/a
Isnt MC++ being redesigned so those __ keywords are no longer required?

"100" <10*@100.com> wrote in message
news:em**************@tk2msftngp13.phx.gbl...
Hi JPRoot,
Ok, VC++ defines 3 accessors for events (for adding, removing and raising
the event).
*add* and *remove* accessors has the visibility which is specified for the
event when it is decalred. *Rise* accesor is almost always protected except when the event is private then and *raise* accessor is private.

What does it mean?
That means that you don't have to do anything in C++ to inherit the base
event. So your code can be transformed to

namespace MyNamespace
{
public __delegate void MyDel();
public __gc class MyBase
{
public:
__event MyDel* MyEvent;

public:
void MyMethod2()
{
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{

public:
void MyMethod()
{
//This will raise the base class' event because raise_MyEvent
method is protected
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,
MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();

MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}

And this will work just perfectly.

This is not the case of C#, though. C# compiler doesn't generate *raise*
accessors for events and it inlines calls delegate's Invoke method whenever it finds language constuction like DelegateMemberName(....).
For the sme line VC++ will generate call to raise_DelegateMemberName(....)
method.
Which means that VC++ programs cannot use classes written in C# because they don't have raise_XXX methods defined as well as if you write the class
hierarchy as in the VC++ examples we discuss C# program will be able to use the parent event only if the C# programmer knows about those raise_XXX
methods.

Who is wrong in this case. I'm really really confused.
If we look in CLI specification (Part I - Architecture) we can find:
Per 8.11.4 Event Definitions
The CTS supports events in precisely the same way that it supports
properties (see clause 8.11.3). The
conventional methods, however, are different and include means for
subscribing and unsubscribing to events as
well as for firing the event.

-------
C# doesn't generate method for *firing* the event.

Per 10.4 Naming Patterns
See also Partition V. 30
While the CTS does not dictate the naming of properties or events, the CLS
does specify a pattern to be
observed.
For Events:
An individual event is created by choosing or defining a delegate type that is used to signal the event. Then,
three methods are created with names based on the name of the event and with a fixed signature. For the
examples below we define an event named Click that uses a delegate type
named EventHandler.
EventAdd, used to add a handler for an event
Pattern: void add_<EventName> (<DelegateType> handler)
Example: void add_Click (EventHandler handler);
EventRemove, used to remove a handler for an event
Pattern: void remove_<EventName> (<DelegateType> handler)
Example: void remove_Click (EventHandler handler);
EventRaise, used to signal that an event has occurred
Pattern: void family raise_<EventName> (Event e)
------
C# creates only two names.
Per 8.10.3 Property and Event Inheritance
....
The source compiler shall generate CIL that directly accesses the methods
named by the events and properties, not the events or properties themselves.
------
C# compiler doesn't use the method decalred for raising the event

And I finaly got lost in my confusion when I saw that no class of the
framework has raise_XXX method.

I have to confess that I haven't read the specs carefully so I might
misunderstood something.
Can anybody explain what CLI specification states and why only VC++
generates and uses *raise* methods?
Neither C# nor VB.NET do that

B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:B8**********************************@microsof t.com...
100,
You are 100% right.

The point I am trying to make is that the Add and Remove are made virtual
when you put the virtual keyword besides the event keyword but not the Raise which I see as a bug(or lack of completeness of the feature) since in
VC++.NET Managed when you put the virtual keyword besides an __event not
only the Add and Remove becomes virtual but also the Raise method, which
makes complete sence!!

Other feature that C# lacks is a way to define the Raise method like you can do in VC++.NET Managed.

Here's the exact same snippet I first posted but in VC++.NET Managed

where event "virtualization" really works!! Also, having it this way, makes it
useless to have OnXXX pattern... or at least less useful :)

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;

namespace MyNamespace
{
__delegate void MyDel();
public __gc class MyBase
{
public:
virtual __event MyDel* MyEvent;

public:
void MyMethod2()
{ // this should call child class event if overriden
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{
protected:
__event MyDel* m_myEventInvokeList;
public:
virtual __event void add_MyEvent(MyDel* d)
{
m_myEventInvokeList += d;
}

virtual __event void remove_MyEvent(MyDel* d)
{
m_myEventInvokeList -= d;
}

protected:
virtual __event void raise_MyEvent()
{
__raise m_myEventInvokeList();
}

public:

void MyMethod()
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base class
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0, MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();
MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}
----- 100 wrote: -----

Hi JPRoot,

IMHO this is indeed very strange way to use base class's events.

And beside
I find it strange it is wrong or at least error prone.

You have to check the event for null before fire it because you
can't know
if you have handlers registered for that event:
if(MyEvent != null) MyEvent();

But this is not the bigest flaw.

When you define an event as virtual actually you define its
accessors (add
and remove) as virtual, but each class in the hierarchy will have
its own
field of type *delegate void MyDel()* to hold the handlers

What does it means? Let me provide a new example.

public delegate void MyDel();

class Foo
{
public virtual MyDel MyEvent;
public FooRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

class Bar: Foo
{
public override MyDel MyEvent;
public BarRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

Now let we have the following code snippet

Foo foo = new Bar();
foo.MyEvent += new MyDel(foo_MyEvent);
Bar bar = (Bar) foo; //we can do that because the object is of type Bar.

bar.BarRaiseMyEvent(); //Everything is just perfect the event fires
bar.FooRaiseMyEvent(); // Bar inherits this method from Foo, but no

event
fires.

Which means that no methods form the base class can fire the event.

Imagine
if you have more classes in the hierarchy....

Why is this happen?
Because doing
foo.MyEvent += new MyDel(foo_MyEvent);
we call MeEvent's *add* accessor polymorphically and the one

decalred in Bar
will be called. It will add the handler to the delegate chain in Bar's field
of type MyDel.
Now when BarRaiseMyEvent calles MyEvent() it uses Bar's delegate

field,
which has something inside.
FooRaiseMyEvent., though, uses Foo's delegate field which has

nothing inside
and no event is fired.
Access to Fields cannot be polymorphical.

To use events declared in the base class use the design pattern
used throughout the framework (OnXXX methods).
I believe it is described somewhere in MSDN but I don't remember

where.
Try to look at

ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconprovidingeventfunctional
ity.htm
HTH
B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:0A**********************************@microsof t.com...
> 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 events since I
never saw it
used anywhere in MSDN documentation/samples?! Or it will just break

when I
upgrade to .NET Framework 2.x in the coming years?
>> namespace MyNamespace
> {
> public delegate void MyDel();
>> public class MyBase
> {
> public virtual event MyDel MyEvent;
> public void MyMethod2()
> {
> MyEvent();
> }
> }
>> public class MyDerived : MyBase
> {
> // Override base class event so that it can
> // be raise from child (here!)
> public override event MyDel MyEvent;
>> public void MyMethod()
> { // Raise event. Without the virtual/override keywords,
> // child classes are not allowed to raise events declared
> // in their base class
> MyEvent();
> }
> }
> }
>> Thanks
> JPRoot
>


Nov 15 '05 #13

P: n/a
100
I don't know in general, but it works either ways for events. Anyway, even
if we use the sintax without __raise the compiler generates call to
raise_XXX method instead of direct call to delegate's Invoke methods as C#
and VB.NET do.

B\rgds
100
"Alvin Bruney" <.> wrote in message
news:uu*************@TK2MSFTNGP11.phx.gbl...
Isnt MC++ being redesigned so those __ keywords are no longer required?

"100" <10*@100.com> wrote in message
news:em**************@tk2msftngp13.phx.gbl...
Hi JPRoot,
Ok, VC++ defines 3 accessors for events (for adding, removing and raising
the event).
*add* and *remove* accessors has the visibility which is specified for the event when it is decalred. *Rise* accesor is almost always protected

except
when the event is private then and *raise* accessor is private.

What does it mean?
That means that you don't have to do anything in C++ to inherit the base
event. So your code can be transformed to

namespace MyNamespace
{
public __delegate void MyDel();
public __gc class MyBase
{
public:
__event MyDel* MyEvent;

public:
void MyMethod2()
{
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{

public:
void MyMethod()
{
//This will raise the base class' event because raise_MyEvent method is protected
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,
MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();

MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}

And this will work just perfectly.

This is not the case of C#, though. C# compiler doesn't generate *raise*
accessors for events and it inlines calls delegate's Invoke method

whenever
it finds language constuction like DelegateMemberName(....).
For the sme line VC++ will generate call to raise_DelegateMemberName(....) method.
Which means that VC++ programs cannot use classes written in C# because

they
don't have raise_XXX methods defined as well as if you write the class
hierarchy as in the VC++ examples we discuss C# program will be able to

use
the parent event only if the C# programmer knows about those raise_XXX
methods.

Who is wrong in this case. I'm really really confused.
If we look in CLI specification (Part I - Architecture) we can find:
Per 8.11.4 Event Definitions
The CTS supports events in precisely the same way that it supports
properties (see clause 8.11.3). The
conventional methods, however, are different and include means for
subscribing and unsubscribing to events as
well as for firing the event.

-------
C# doesn't generate method for *firing* the event.

Per 10.4 Naming Patterns
See also Partition V. 30
While the CTS does not dictate the naming of properties or events, the CLS does specify a pattern to be
observed.
For Events:
An individual event is created by choosing or defining a delegate type

that
is used to signal the event. Then,
three methods are created with names based on the name of the event and

with
a fixed signature. For the
examples below we define an event named Click that uses a delegate type
named EventHandler.
EventAdd, used to add a handler for an event
Pattern: void add_<EventName> (<DelegateType> handler)
Example: void add_Click (EventHandler handler);
EventRemove, used to remove a handler for an event
Pattern: void remove_<EventName> (<DelegateType> handler)
Example: void remove_Click (EventHandler handler);
EventRaise, used to signal that an event has occurred
Pattern: void family raise_<EventName> (Event e)
------
C# creates only two names.
Per 8.10.3 Property and Event Inheritance
....
The source compiler shall generate CIL that directly accesses the methods named by the events and properties, not the events or properties

themselves.

------
C# compiler doesn't use the method decalred for raising the event

And I finaly got lost in my confusion when I saw that no class of the
framework has raise_XXX method.

I have to confess that I haven't read the specs carefully so I might
misunderstood something.
Can anybody explain what CLI specification states and why only VC++
generates and uses *raise* methods?
Neither C# nor VB.NET do that

B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:B8**********************************@microsof t.com...
100,
You are 100% right.

The point I am trying to make is that the Add and Remove are made virtual
when you put the virtual keyword besides the event keyword but not the

Raise
which I see as a bug(or lack of completeness of the feature) since in
VC++.NET Managed when you put the virtual keyword besides an __event not
only the Add and Remove becomes virtual but also the Raise method, which
makes complete sence!!

Other feature that C# lacks is a way to define the Raise method like you can do in VC++.NET Managed.

Here's the exact same snippet I first posted but in VC++.NET Managed where
event "virtualization" really works!! Also, having it this way, makes it
useless to have OnXXX pattern... or at least less useful :)

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;

namespace MyNamespace
{
__delegate void MyDel();
public __gc class MyBase
{
public:
virtual __event MyDel* MyEvent;

public:
void MyMethod2()
{ // this should call child class event if overriden
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{
protected:
__event MyDel* m_myEventInvokeList;
public:
virtual __event void add_MyEvent(MyDel* d)
{
m_myEventInvokeList += d;
}

virtual __event void remove_MyEvent(MyDel* d)
{
m_myEventInvokeList -= d;
}

protected:
virtual __event void raise_MyEvent()
{
__raise m_myEventInvokeList();
}

public:

void MyMethod()
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base class
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,

MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();
MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}
----- 100 wrote: -----

Hi JPRoot,

IMHO this is indeed very strange way to use base class's events.

And
beside
I find it strange it is wrong or at least error prone.

You have to check the event for null before fire it because you

can't
know
if you have handlers registered for that event:
if(MyEvent != null) MyEvent();

But this is not the bigest flaw.

When you define an event as virtual actually you define its

accessors
(add
and remove) as virtual, but each class in the hierarchy will have

its
own
field of type *delegate void MyDel()* to hold the handlers

What does it means? Let me provide a new example.

public delegate void MyDel();

class Foo
{
public virtual MyDel MyEvent;
public FooRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

class Bar: Foo
{
public override MyDel MyEvent;
public BarRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

Now let we have the following code snippet

Foo foo = new Bar();
foo.MyEvent += new MyDel(foo_MyEvent);
Bar bar = (Bar) foo; //we can do that because the object is of

type Bar.

bar.BarRaiseMyEvent(); //Everything is just perfect the event

fires bar.FooRaiseMyEvent(); // Bar inherits this method from Foo, but no event
fires.

Which means that no methods form the base class can fire the
event. Imagine
if you have more classes in the hierarchy....

Why is this happen?
Because doing
foo.MyEvent += new MyDel(foo_MyEvent);
we call MeEvent's *add* accessor polymorphically and the one decalred
in Bar
will be called. It will add the handler to the delegate chain in

Bar's field
of type MyDel.
Now when BarRaiseMyEvent calles MyEvent() it uses Bar's delegate

field,
which has something inside.
FooRaiseMyEvent., though, uses Foo's delegate field which has

nothing
inside
and no event is fired.
Access to Fields cannot be polymorphical.

To use events declared in the base class use the design pattern

used throughout the framework (OnXXX methods).
I believe it is described somewhere in MSDN but I don't remember

where.
Try to look at

ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconprovidingeventfunctional ity.htm
HTH
B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:0A**********************************@microsof t.com...
> 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 events since I

never
saw it
used anywhere in MSDN documentation/samples?! Or it will just

break when I
upgrade to .NET Framework 2.x in the coming years?
>> namespace MyNamespace
> {
> public delegate void MyDel();
>> public class MyBase
> {
> public virtual event MyDel MyEvent;
> public void MyMethod2()
> {
> MyEvent();
> }
> }
>> public class MyDerived : MyBase
> {
> // Override base class event so that it can
> // be raise from child (here!)
> public override event MyDel MyEvent;
>> public void MyMethod()
> { // Raise event. Without the virtual/override keywords,
> // child classes are not allowed to raise events declared
> // in their base class
> MyEvent();
> }
> }
> }
>> Thanks
> JPRoot
>



Nov 15 '05 #14

P: n/a
Ignore this guy he is spoofing my email account. For credibility purposes I
suppose.

--
-----------
Got TidBits?
Get it here: www.networkip.net/tidbits
"Alvin Bruney" <.> wrote in message
news:uu*************@TK2MSFTNGP11.phx.gbl...
Isnt MC++ being redesigned so those __ keywords are no longer required?

"100" <10*@100.com> wrote in message
news:em**************@tk2msftngp13.phx.gbl...
Hi JPRoot,
Ok, VC++ defines 3 accessors for events (for adding, removing and raising
the event).
*add* and *remove* accessors has the visibility which is specified for the event when it is decalred. *Rise* accesor is almost always protected

except
when the event is private then and *raise* accessor is private.

What does it mean?
That means that you don't have to do anything in C++ to inherit the base
event. So your code can be transformed to

namespace MyNamespace
{
public __delegate void MyDel();
public __gc class MyBase
{
public:
__event MyDel* MyEvent;

public:
void MyMethod2()
{
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{

public:
void MyMethod()
{
//This will raise the base class' event because raise_MyEvent method is protected
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,
MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();

MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}

And this will work just perfectly.

This is not the case of C#, though. C# compiler doesn't generate *raise*
accessors for events and it inlines calls delegate's Invoke method

whenever
it finds language constuction like DelegateMemberName(....).
For the sme line VC++ will generate call to raise_DelegateMemberName(....) method.
Which means that VC++ programs cannot use classes written in C# because

they
don't have raise_XXX methods defined as well as if you write the class
hierarchy as in the VC++ examples we discuss C# program will be able to

use
the parent event only if the C# programmer knows about those raise_XXX
methods.

Who is wrong in this case. I'm really really confused.
If we look in CLI specification (Part I - Architecture) we can find:
Per 8.11.4 Event Definitions
The CTS supports events in precisely the same way that it supports
properties (see clause 8.11.3). The
conventional methods, however, are different and include means for
subscribing and unsubscribing to events as
well as for firing the event.

-------
C# doesn't generate method for *firing* the event.

Per 10.4 Naming Patterns
See also Partition V. 30
While the CTS does not dictate the naming of properties or events, the CLS does specify a pattern to be
observed.
For Events:
An individual event is created by choosing or defining a delegate type

that
is used to signal the event. Then,
three methods are created with names based on the name of the event and

with
a fixed signature. For the
examples below we define an event named Click that uses a delegate type
named EventHandler.
EventAdd, used to add a handler for an event
Pattern: void add_<EventName> (<DelegateType> handler)
Example: void add_Click (EventHandler handler);
EventRemove, used to remove a handler for an event
Pattern: void remove_<EventName> (<DelegateType> handler)
Example: void remove_Click (EventHandler handler);
EventRaise, used to signal that an event has occurred
Pattern: void family raise_<EventName> (Event e)
------
C# creates only two names.
Per 8.10.3 Property and Event Inheritance
....
The source compiler shall generate CIL that directly accesses the methods named by the events and properties, not the events or properties

themselves.

------
C# compiler doesn't use the method decalred for raising the event

And I finaly got lost in my confusion when I saw that no class of the
framework has raise_XXX method.

I have to confess that I haven't read the specs carefully so I might
misunderstood something.
Can anybody explain what CLI specification states and why only VC++
generates and uses *raise* methods?
Neither C# nor VB.NET do that

B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:B8**********************************@microsof t.com...
100,
You are 100% right.

The point I am trying to make is that the Add and Remove are made virtual
when you put the virtual keyword besides the event keyword but not the

Raise
which I see as a bug(or lack of completeness of the feature) since in
VC++.NET Managed when you put the virtual keyword besides an __event not
only the Add and Remove becomes virtual but also the Raise method, which
makes complete sence!!

Other feature that C# lacks is a way to define the Raise method like you can do in VC++.NET Managed.

Here's the exact same snippet I first posted but in VC++.NET Managed where
event "virtualization" really works!! Also, having it this way, makes it
useless to have OnXXX pattern... or at least less useful :)

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;

namespace MyNamespace
{
__delegate void MyDel();
public __gc class MyBase
{
public:
virtual __event MyDel* MyEvent;

public:
void MyMethod2()
{ // this should call child class event if overriden
__raise MyEvent();
}
};

public __gc class MyDerived : public MyBase
{
protected:
__event MyDel* m_myEventInvokeList;
public:
virtual __event void add_MyEvent(MyDel* d)
{
m_myEventInvokeList += d;
}

virtual __event void remove_MyEvent(MyDel* d)
{
m_myEventInvokeList -= d;
}

protected:
virtual __event void raise_MyEvent()
{
__raise m_myEventInvokeList();
}

public:

void MyMethod()
{ // Raise event. Without the virtual/override keywords,
// child classes are not allowed to raise events declared
// in their base class
__raise MyEvent();
}
};

public __gc class EventReceiver
{
public:
static void MyEventHandler()
{
System::Console::WriteLine("Event fired!");
}
};
};

int _tmain(void)
{
MyNamespace::MyDerived* aa = new MyNamespace::MyDerived();
MyNamespace::MyBase* bb = aa;
MyNamespace::MyDel* receiver = new MyNamespace::MyDel( 0,

MyNamespace::EventReceiver::MyEventHandler );
aa->MyEvent += receiver;
bb->MyEvent += receiver;
aa->MyMethod();
aa->MyMethod2();
MyNamespace::MyBase* cc = new MyNamespace::MyBase();
cc->MyEvent += receiver;
cc->MyMethod2();
System::Console::ReadLine();
return 0;
}
----- 100 wrote: -----

Hi JPRoot,

IMHO this is indeed very strange way to use base class's events.

And
beside
I find it strange it is wrong or at least error prone.

You have to check the event for null before fire it because you

can't
know
if you have handlers registered for that event:
if(MyEvent != null) MyEvent();

But this is not the bigest flaw.

When you define an event as virtual actually you define its

accessors
(add
and remove) as virtual, but each class in the hierarchy will have

its
own
field of type *delegate void MyDel()* to hold the handlers

What does it means? Let me provide a new example.

public delegate void MyDel();

class Foo
{
public virtual MyDel MyEvent;
public FooRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

class Bar: Foo
{
public override MyDel MyEvent;
public BarRaiseMyEvent()
{
if(MyEvent != null) MyEvent();
}
}

Now let we have the following code snippet

Foo foo = new Bar();
foo.MyEvent += new MyDel(foo_MyEvent);
Bar bar = (Bar) foo; //we can do that because the object is of

type Bar.

bar.BarRaiseMyEvent(); //Everything is just perfect the event

fires bar.FooRaiseMyEvent(); // Bar inherits this method from Foo, but no event
fires.

Which means that no methods form the base class can fire the
event. Imagine
if you have more classes in the hierarchy....

Why is this happen?
Because doing
foo.MyEvent += new MyDel(foo_MyEvent);
we call MeEvent's *add* accessor polymorphically and the one decalred
in Bar
will be called. It will add the handler to the delegate chain in

Bar's field
of type MyDel.
Now when BarRaiseMyEvent calles MyEvent() it uses Bar's delegate

field,
which has something inside.
FooRaiseMyEvent., though, uses Foo's delegate field which has

nothing
inside
and no event is fired.
Access to Fields cannot be polymorphical.

To use events declared in the base class use the design pattern

used throughout the framework (OnXXX methods).
I believe it is described somewhere in MSDN but I don't remember

where.
Try to look at

ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconprovidingeventfunctional ity.htm
HTH
B\rgds
100

"JPRoot" <jp****@hotmail.com> wrote in message
news:0A**********************************@microsof t.com...
> 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 events since I

never
saw it
used anywhere in MSDN documentation/samples?! Or it will just

break when I
upgrade to .NET Framework 2.x in the coming years?
>> namespace MyNamespace
> {
> public delegate void MyDel();
>> public class MyBase
> {
> public virtual event MyDel MyEvent;
> public void MyMethod2()
> {
> MyEvent();
> }
> }
>> public class MyDerived : MyBase
> {
> // Override base class event so that it can
> // be raise from child (here!)
> public override event MyDel MyEvent;
>> public void MyMethod()
> { // Raise event. Without the virtual/override keywords,
> // child classes are not allowed to raise events declared
> // in their base class
> MyEvent();
> }
> }
> }
>> Thanks
> JPRoot
>



Nov 15 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.