473,396 Members | 1,864 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 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 2496
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Steve W. | last post by:
I just read the section (and did the exercise) in the C# Step by Step book that covers Explict Interface Implementation (where you specify in the method implementation the specific interface that...
2
by: cody | last post by:
it seems to me that explicit interface implementation does not work with events: class Foo : IContentchangeableControl { event EventHandler MyNs.IContentchangeableControl.ContentChanged; } ...
4
by: Mathieu Cartoixa | last post by:
Hi, I have been annoyed in one of my recent projects with a problem related to the explicit implementation of an interface on a value type. I will take an example to show the problem. Say we...
14
by: Noone | last post by:
Hello all, Ok, I want to create a program that will load plugins (dll's) from a plugin folder. I can create the forms and put them into a dll but I cannot actually add them dynamically at run...
0
by: Ken | last post by:
Hi I have a little application that does datavalidation. It supports dynamically loaded plugins (you drop a dll with a class implementing IValidator<Tin the same dir as the main application)....
0
by: Brandon Driesen | last post by:
The following illustrates my question. Why is it when I bind to an a collection of items whose interface implementation is explicit, there is an error during the binding process wherein the error...
1
by: recherche | last post by:
Hola! I tried the following public implementation of interface indexer by struct (Code Snippet 1) in private and explicit implementation by struct (Code Snippet 2) but in vain. Please help! ...
1
by: =?Utf-8?B?Sk0=?= | last post by:
In an application I have an interface with methods and properties. The interface is used on a Class (ie class MyClass : IMyClassA, IMyClassB). On a windows form I define a BindingSource...
2
by: puzzlecracker | last post by:
I don't see the purpose of explicit interface implementation other than to hide its signature in the class that implements it, and, instead, write your own, perhaps with a different signature,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.