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

Jeffrey Tan MSFT forget me? Virtual Override Events Inheritance

P: n/a
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?= <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 #1
Share this Question
Share on Google+
8 Replies


P: n/a

Hi,

Sorry, it seems that I missed the original thread. Let's continue in this
thread.

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.

Nov 15 '05 #2

P: n/a

Hi,

Oh, as I see in original post, 100 at last has posted a reply to you.
Does that make sense to you?

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.

Nov 15 '05 #3

P: n/a
100 explained the difference between C++ and C#, and yes the explaination
make a lot of sense to explain the current behavior. But it also means that
the virtual/override keyword in C# on an event is useless since the raise
method is not made virtual, like it is supposed to like the Add and Remove.

It so much make sense in C++.NET Managed that I cannot beleive that it was
made by design this way in C#.

I would like to ear from you (a Microsoft representative) if it is by
design(A) or if it is a bug(B)?

....I strongly hope it is a bug! ...so that it will be corrected :-) ...

Thanks a lot!
JPRoot

PS: I don't know where we can post suggestions but I would like very much to
see in next version of C# to have a way to implement the Raise method like
we can do in C++.NET Managed.

""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
news:ZS**************@cpmsftngxa06.phx.gbl...

Hi,

Oh, as I see in original post, 100 at last has posted a reply to you.
Does that make sense to you?

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.

Nov 15 '05 #4

P: n/a
Seems that C# is not CLS compliant!
-----
http://msdn.microsoft.com/library/de...cification.asp
Events - Modifiers - The methods for adding, removing, and raising an event
must all be static, all be virtual, or all be instance.
-----
In C# case, it does not respect the "must all be" rule...

Hopping again that I'm wrong...

Thanks for your help... appreciated!
JPRoot

C# is so a nice language, with templates coming soon... nice...

""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
news:ZS**************@cpmsftngxa06.phx.gbl...

Hi,

Oh, as I see in original post, 100 at last has posted a reply to you.
Does that make sense to you?

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.

Nov 15 '05 #5

P: n/a

Hi,

Sorry for letting you waiting for so long time.
I do not feel well these days and leave for sick yesterday. Ok, forget it,
let's work on your issue.

For your issue, I think it is an interesting problem, I have reproduced
your problem.
I will spend more time on this to find if this is by design. I do as soon
as I can.
Thanks for your understanding.

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.

Nov 15 '05 #6

P: n/a

Hi,

I still did not find a solid explanation for this issue, I will go and find
someone else to help you on this.
Thanks for your understanding.

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.

Nov 15 '05 #7

P: n/a

Hi,

I still did not find a solid explanation for this issue, I will go and find
someone else to help you on this.
Thanks for your understanding.

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.

Nov 15 '05 #8

P: n/a

Hi,

This is by design in the C# language though not really a CLS issue though.

The reference to MyEvent in the base class refers (non-virtually) to the
compiler generated backing store for the event. While the client of the
event connected to the event through a virtual call to the derived add
accessor via the += operator. The real issue is that in the derived class
there is two backing stores for the event, one in the base class, one in
the derived class. Declaring an override event with the field syntax
(rather than the property syntax) is in general not what you want to do.
Either the base event should be abstract, or (more likely) the override
event should be declared with the property syntax, and defer storage (and
the method which raises the event) to the base class. Something like:

class Class1
{
public delegate void MyDel();
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
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.FooRaiseMyEvent();
Console.Read();
}

class Foo
{
public virtual event MyDel MyEvent;
public void FooRaiseMyEvent()
{
if(MyEvent != null)
{
Console.WriteLine("FooRaiseMyEvent");
MyEvent();
}
}
}

class Bar: Foo
{
public override event MyDel MyEvent
{
add
{
base.MyEvent += value;
}
remove
{
base.MyEvent -= value;
}
}
}

public static void foo_MyEvent()
{
Console.WriteLine("get called");
}
}

If you still feel it uncomfortable, you can provide your suggest to :
http://register.microsoft.com/mswish/suggestion.asp or mail to
ms****@microsoft.com

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.

Nov 15 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.