G
Guest
Hi M. Jeffrey Tan,
Just hopping you didn't forget me?
Thanks
JPRoot
----- \"Jeffrey Tan[MSFT]\" wrote: -----
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.
----- JPRoot wrote: -----
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;
}
--------------------
| Thread-Topic: Virtual Override Events Inheritance
| thread-index: AcOqNrWCuoOYF9SrS3WjsXs6rYhgEQ==
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| From: =?Utf-8?B?SlBSb290?= <[email protected]>
| References: <[email protected]><##[email protected]>
| Subject: Re: Virtual Override Events Inheritance
| Date: Thu, 13 Nov 2003 14:37:24 -0800
| Lines: 39
| Message-ID: <[email protected]>
| 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: -----
It's supported and documented alright. See
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_10_7.asp
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_10_7_4.a
sp
Mattias
--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
|
Just hopping you didn't forget me?

Thanks
JPRoot
----- \"Jeffrey Tan[MSFT]\" wrote: -----
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.
----- JPRoot wrote: -----
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;
}
--------------------
| Thread-Topic: Virtual Override Events Inheritance
| thread-index: AcOqNrWCuoOYF9SrS3WjsXs6rYhgEQ==
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| From: =?Utf-8?B?SlBSb290?= <[email protected]>
| References: <[email protected]><##[email protected]>
| Subject: Re: Virtual Override Events Inheritance
| Date: Thu, 13 Nov 2003 14:37:24 -0800
| Lines: 39
| Message-ID: <[email protected]>
| 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-us/csspec/html/vclrfcsharpspec_10_7.asp
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_10_7_4.a
sp
Mattias
--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
|