polymorphism/boxing question

L

lorenzon

I've run into a problem in some code involving two class hierarchies
that I can't figure out: I have an event hierachy topped with an
interface, let's say-

IEvent,
EventA : IEvent,
EventB : IEvent

And some handlers-

abstract EventHandler
EventHandler1 : EventHandler

Now in the abstract EventHandler class I have a method which processes
events -

virtual void ProcessEvent(IEvent e) {}

and a loop which calls that method for every event I put on the
handler object (it runs in its own thread, but that's irrelevant). I
want the classes to process events like this:

class EventHandler1 : EventHandler
{
protected override void ProcessEvent(IEvent e)
{
//do some default processing in case there is no specific handler
}

protected void ProcessEvent(EventA e)
{
//specific processing for EventA type events
}

protected void ProcessEvent(EventB e)
{
//specific processing for EventB type events
}
}

So when the EventHandler method tries to process an event, it goes to
the ProcessEvent method for the most derived IEvent class for the
event object being passed in. What happens as it is is that the
ProcessEvent(IEvent) method is called, presumably because the event
object is boxed as an IEvent where it is held in the superclass.

I was kind of hoping that the runtime would just know what type the
event was, and call the appropriate method for that class. It doesn't
though, so is there a) some combination of language features such as
virtual / abstract / override that i can employ to achieve this, or b)
some way to dynamically unbox the event in the superclass? I looked
into dynamic casting and it doesn't seem to be possible in c#. But the
object knows what it is so it should be possible to extract it out of
its IEvent box and invoke an appropriate method through normal
polymorphism right?
 
L

lorenzon

quick update by self:
after looking into it it almost seems like this is impossible as I
read that C# determines which overload to invoke for a given call at
compile time. This seems to me to be lame, and kind of hobbles
polymorphism doesn't it? At least I should be able to unbox my
variable from its generic interface type and have the call made on it
then.
 
B

Bruce Wood

I've run into a problem in some code involving two class hierarchies
that I can't figure out: I have an event hierachy topped with an
interface, let's say-

IEvent,
EventA : IEvent,
EventB : IEvent

And some handlers-

abstract EventHandler
EventHandler1 : EventHandler

Now in the abstract EventHandler class I have a method which processes
events -

virtual void ProcessEvent(IEvent e) {}

and a loop which calls that method for every event I put on the
handler object (it runs in its own thread, but that's irrelevant). I
want the classes to process events like this:

class EventHandler1 : EventHandler
{
protected override void ProcessEvent(IEvent e)
{
//do some default processing in case there is no specific handler
}

protected void ProcessEvent(EventA e)
{
//specific processing for EventA type events
}

protected void ProcessEvent(EventB e)
{
//specific processing for EventB type events
}

}

So when the EventHandler method tries to process an event, it goes to
the ProcessEvent method for the most derived IEvent class for the
event object being passed in. What happens as it is is that the
ProcessEvent(IEvent) method is called, presumably because the event
object is boxed as an IEvent where it is held in the superclass.

I was kind of hoping that the runtime would just know what type the
event was, and call the appropriate method for that class. It doesn't
though, so is there a) some combination of language features such as
virtual / abstract / override that i can employ to achieve this, or b)
some way to dynamically unbox the event in the superclass? I looked
into dynamic casting and it doesn't seem to be possible in c#. But the
object knows what it is so it should be possible to extract it out of
its IEvent box and invoke an appropriate method through normal
polymorphism right?

Is there a reason why you can't put ProcessEvent within the IEvent
interface itself? Then you _could_ use polymorphism to handle the
different types of events. It also has the advantage that every time
you implement IEvent in another class you don't have to add a method
to your central event handler to handle the new case: it's handled in
the class itself.
 
J

Jon Skeet [C# MVP]

quick update by self:
after looking into it it almost seems like this is impossible as I
read that C# determines which overload to invoke for a given call at
compile time. This seems to me to be lame, and kind of hobbles
polymorphism doesn't it? At least I should be able to unbox my
variable from its generic interface type and have the call made on it
then.

Okay, to start with: there's no boxing involved in your examples.
Boxing is a matter of representing a value type value as a reference
type instance. You haven't shown any value types being involved at all.

And yes, you're right: overloading is performed at compile time. That
doesn't hobble polymorphism, however, which is more about *overriding*
than overloading.

"Double dispatch" may be the answer to your issues, however. See
http://en.wikipedia.org/wiki/Double_dispatch
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top