473,320 Members | 1,724 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,320 software developers and data experts.

Virtual Override Events Inheritance

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
14 12076
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
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
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
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
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
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
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
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

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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: news.microsoft.com | last post by:
Hi, It is possible to override a non virtual method with the "new" keyword So how is this different from specifying a method as virtual then providing the override keyword? Is there any...
4
by: Rafael Veronezi | last post by:
I have some questions about override in inheritance, and virtual members. I know that you can you override a method by two ways in C#, one, is overriding with the new keyword, like: public new...
8
by: JPRoot | last post by:
Hi M. Jeffrey Tan, Just hopping you didn't forget me? :) Thanks JPRoot ----- \"Jeffrey Tan\" wrote: -----
5
by: Mark Broadbent | last post by:
Oh yes its that chestnut again! Ive gone over the following (http://www.yoda.arachsys.com/csharp/faq/ -thanks Jon!) again regarding this subject and performed a few of my own tests. I have two...
5
by: Action | last post by:
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...
14
by: Bruno van Dooren | last post by:
Hi all, i am having a problems with inheritance. consider the following: class A { public: A(int i){;} };
5
by: Marcel Hug | last post by:
Hi NG ! I'm new in C# and I'm reading a book about the fundamentals and concepts. In the chapter Methods it's written to use virtual, if i would like to override the method in a subclass. This...
2
by: junw2000 | last post by:
In the following code: #include <iostream> using namespace std; class V { public: int i; virtual void f() { cout << "V::f()" << endl;}
8
by: puzzlecracker | last post by:
The statement is taken from FAQ . What about non-virtual functions? Can they be overriden? I still don't see a good justification to prefer private inheritance over composition. In fact, I have...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
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...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
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...

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.