472,119 Members | 1,588 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,119 software developers and data experts.

Explicit Interface Implementation And Events

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 GeneralEventHandler(object sender, GeneralEventArgs
ex);
public delegate void SpecificEventHandler(object sender, SpecificEventArgs
ex);

public class GeneralEventArgs : EventArgs
{
public string general = "General";
}

public class SpecificEventArgs : GeneralEventArgs
{
public string specific = "Specific";
}
public interface BaseInterface
{
event GeneralEventHandler GeneralEvent;
}

public class ConcreteClassSpecific: BaseInterface
{
// explicit interface implementation, I need to actually specify
// the add/remove accessors
GeneralEventHandler specificEvent;
event InheritanceTest.GeneralEventHandler BaseInterface.GeneralEvent
{
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}

// This means that subscribers have to use SpecificEventHandler which
// allows them to access its specific string field
public event SpecificEventHandler GeneralEvent;

protected void OnEvent()
{
if (specificEvent != null)
{
specificEvent(null, new GeneralEventArgs());
}

if (GeneralEvent != null)
{
GeneralEvent(this, new SpecificEventArgs());
}
}

public void RaiseEvent()
{
OnEvent();
}
}
Nov 17 '05 #1
2 2385
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,
"SpecificEvent" along side of the implementation for "GeneralEvent". 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.GeneralEventHandler BaseInterface.GeneralEvent
{
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}

--
Dave Sexton
dave@www..jwaonline..com
-----------------------------------------------------------------------
"COLIN JACK" <cj********@blueyonder.co.uk> wrote in message news:wK*****************@fe2.news.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 GeneralEventHandler(object sender, GeneralEventArgs ex);
public delegate void SpecificEventHandler(object sender, SpecificEventArgs ex);

public class GeneralEventArgs : EventArgs
{
public string general = "General";
}

public class SpecificEventArgs : GeneralEventArgs
{
public string specific = "Specific";
}
public interface BaseInterface
{
event GeneralEventHandler GeneralEvent;
}

public class ConcreteClassSpecific: BaseInterface
{
// explicit interface implementation, I need to actually specify
// the add/remove accessors
GeneralEventHandler specificEvent;
event InheritanceTest.GeneralEventHandler BaseInterface.GeneralEvent
{
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}

// This means that subscribers have to use SpecificEventHandler which
// allows them to access its specific string field
public event SpecificEventHandler GeneralEvent;

protected void OnEvent()
{
if (specificEvent != null)
{
specificEvent(null, new GeneralEventArgs());
}

if (GeneralEvent != null)
{
GeneralEvent(this, new SpecificEventArgs());
}
}

public void RaiseEvent()
{
OnEvent();
}
}

Nov 17 '05 #2
Hi Dave,

Thanks for the reply, very useful to read someone else's opinion.

First off yes using the "specificEvent" 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
GeneralEventHandler delegate if you cast the publisher
(ConcreteClassSpecific) to the interface(BaseInterface). 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
ConcreteClassSpecific 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 SubscribeToEvents()
{
ConcreteClassSpecific myObject = new ConcreteClassSpecific();
myObject.GeneralEvent += new
SpecificEventHandler(specific_GeneralEvent);

BaseInterface interfaceBase = (BaseInterface)myObject;
interfaceBase.GeneralEvent +=new
GeneralEventHandler(interfaceBase_GeneralEvent);

myObject.RaiseEvent();
}

private void specific_GeneralEvent(object sender, SpecificEventArgs
ex)
{
}

private void interfaceBase_GeneralEvent(object sender,
GeneralEventArgs 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, "SpecificEvent" along side of the implementation for "GeneralEvent". 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.GeneralEventHandler BaseInterface.GeneralEvent {
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}

--
Dave Sexton
dave@www..jwaonline..com

----------------------------------------------------------------------- "COLIN JACK" <cj********@blueyonder.co.uk> wrote in message

news:wK*****************@fe2.news.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 GeneralEventHandler(object sender, GeneralEventArgs ex); public delegate void SpecificEventHandler(object sender, SpecificEventArgs ex);
public class GeneralEventArgs : EventArgs
{
public string general = "General";
}

public class SpecificEventArgs : GeneralEventArgs
{
public string specific = "Specific";
}
public interface BaseInterface
{
event GeneralEventHandler GeneralEvent;
}

public class ConcreteClassSpecific: BaseInterface
{
// explicit interface implementation, I need to actually specify
// the add/remove accessors
GeneralEventHandler specificEvent;
event InheritanceTest.GeneralEventHandler BaseInterface.GeneralEvent {
add
{
specificEvent += value;
}
remove
{
specificEvent -= value;
}
}

// This means that subscribers have to use SpecificEventHandler which // allows them to access its specific string field
public event SpecificEventHandler GeneralEvent;

protected void OnEvent()
{
if (specificEvent != null)
{
specificEvent(null, new GeneralEventArgs());
}

if (GeneralEvent != null)
{
GeneralEvent(this, new SpecificEventArgs());
}
}

public void RaiseEvent()
{
OnEvent();
}
}


Nov 17 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Brandon Driesen | last post: by
2 posts views Thread by puzzlecracker | last post: by
reply views Thread by leo001 | last post: by

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.