Hi Dave,
Thanks for the reply, very useful to read someone else's opinion.
First off yes using the "specificEv ent" was an oversight, I should have
read through the code before posting :)
However I dont see that i'm breaking the contract. I say this because
you can still subscribe to and receive the GeneralEvent using the
GeneralEventHan dler delegate if you cast the publisher
(ConcreteClassS pecific) to the interface(BaseI nterface). However if
you, as a subscriber, want the more specific event arguments then you
subscribe to the event using a normal reference to the object (using a
ConcreteClassSp ecific reference). I've tried to show this in the
attached snippet.
I may be wrong but I see this as the same as using explicit interface
implementation to provide type safety with methods.
Your right about me trying to avoid following the normal event desing
pattern as I dont like the idea that I'm raising an event and the
receiver actually knows that the event args are a derived class so they
do a cast.
Ta,
Colin
private void SubscribeToEven ts()
{
ConcreteClassSp ecific myObject = new ConcreteClassSp ecific();
myObject.Genera lEvent += new
SpecificEventHa ndler(specific_ GeneralEvent);
BaseInterface interfaceBase = (BaseInterface) myObject;
interfaceBase.G eneralEvent +=new
GeneralEventHan dler(interfaceB ase_GeneralEven t);
myObject.RaiseE vent();
}
private void specific_Genera lEvent(object sender, SpecificEventAr gs
ex)
{
}
private void interfaceBase_G eneralEvent(obj ect sender,
GeneralEventArg s ex)
{
}
Dave wrote:
I don't see your implementation as necessarily, "sloppy", however the
design patter for delegates states the use of "object" as sender and "EventArgs" as the args for the fact that certain events
may require usage of different "senders" and "args" which these base types will allow via inheritance. To prevent having to cast, I
think your solution is fine.
I'd also like to say that it may not be the best design to have an
interface event "overriden" . The purpose of an Interface is to provide a contract, but your breaching this contract. Maybe you
should have a different event on the implementing type named, "SpecificEv ent" along side of the implementation for "GeneralEve nt".
It's hard to say without knowing the business logic behind the events themselves.
BTW, your accessors are using "specificEvent+ =" when they should be
using "GeneralEvent+= ", correct? Maybe just an oversight: event InheritanceTest .GeneralEventHa ndler
BaseInterface.G eneralEvent {
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}
--
Dave Sexton
dave@www..jwaon line..com
----------------------------------------------------------------------- "COLIN JACK" <cj********@blu eyonder.co.uk> wrote in message
news:wK******** *********@fe2.n ews.blueyonder. co.uk...
Hi All,
I've got a situation where I'm implementing an interface
(BaseInterface in example below) and I want to use explicity interface implementation of an event so that I can add type safety. To see
what I mean look at the example below where the class implementing the interface actually wants the event to be for a
more specific delegate.
Now this seems to work but the code, to me is unnecessarily ugly.
This leaves me wondering if this is something other people do and if so is there a better way of doing it?
I should also say the reason I'm doing it is in a real situation I
want to have a class implementing an interface raising the event with EventArguments that are derived from the ones that the
delegate in the interface uses, doing so stops me having to cast the event arguments in the event handler.
Thanks in advance,
Colin Jack
public delegate void GeneralEventHan dler(object sender,
GeneralEventArg s ex); public delegate void SpecificEventHa ndler(object sender,
SpecificEventAr gs ex);
public class GeneralEventArg s : EventArgs
{
public string general = "General";
}
public class SpecificEventAr gs : GeneralEventArg s
{
public string specific = "Specific";
}
public interface BaseInterface
{
event GeneralEventHan dler GeneralEvent;
}
public class ConcreteClassSp ecific: BaseInterface
{
// explicit interface implementation, I need to actually specify
// the add/remove accessors
GeneralEventHan dler specificEvent;
event InheritanceTest .GeneralEventHa ndler
BaseInterface.G eneralEvent {
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}
// This means that subscribers have to use SpecificEventHa ndler
which // allows them to access its specific string field
public event SpecificEventHa ndler GeneralEvent;
protected void OnEvent()
{
if (specificEvent != null)
{
specificEvent(n ull, new GeneralEventArg s());
}
if (GeneralEvent != null)
{
GeneralEvent(th is, new SpecificEventAr gs());
}
}
public void RaiseEvent()
{
OnEvent();
}
}