interesting problem with events inherited from interfaces

  • Thread starter Wiktor Zychla [C# MVP]
  • Start date
W

Wiktor Zychla [C# MVP]

Hi,

suppose there are two interfaces that contain methods with the same name
but different signature:

interface I1 { void F(); }
interface I2 { int F(); }

it is then easy to implement these two interfaces on a single class with
interface prefixes:

class T : I1, I2 {
void I1.F() { ... };
int I2.F() { ... };
}

its obvious.

however, I am stuck trying the same with events:

public delegate void VD1();
public delegate void VD2();

interface I1 { event VD1 E(); }
interface I2 { event VD2 E(); }

following does not work:

class T : I1, I2 {
event VD1 I1.E;
event VD2 I2.E;
}

error CS0071: An explicit interface implementation of an event must use
property syntax.

let's try to provide an explicit implementation:

class T : I1, I2 {
event VD1 I1.E { add{} remove{} }
event VD2 I2.E { add{} remove{} }
}

it compiles but will probably not work (or will it?) because of empty
add/remove clausules, however I do not think I should be forced to provide
an implementation because I do not like anything more than the standard
behaviour.

although the code above compiles (even with these empty clausules), another
problem arises - I have no idea how to test these events (raise them):

public void test_I1()
{
if ( E != null ) E();
}
test.cs: error CS0103: The name 'E' does not exist in the class or namespace
'Test'

public void test_I1()
{
if ( I1.E != null ) I1.E();
}
test.cs: error CS0079: The event 'I1.E' can only appear on the left hand
side of += or -=

Questions:
1. how do I correctly implement events with the same name coming from
different interfaces?
2. how do I call these events from other methods?

[I should probably say that the problem occured while I was trying to port
some MSIL autogenerated code to C#. It seems to me as another C# restriction
in comparision to MSIL. If it just cannot be done because of C# syntax
restrictions, I will accept that. I just need a clarification. The docs
seems unclear to me on that.]

Regards,
Wiktor Zychla

a piece of code to play with:
------------------------------------------------------------------
using System;

public delegate void VD1();
public delegate void VD2();

public interface I1 {
// void F();
event VD1 E;
}
public interface I2 {
// int F();
event VD2 E;
}

public class Test : I1, I2
{
event VD1 I1.E { add{} remove{} }
event VD2 I2.E { add{} remove{} }

public void vd1_i() { Console.WriteLine( "vd1" ); }
public void Raise_VD1()
{
if ( E != null ) E();
}

// void I1.F() { Console.WriteLine( "I1" ); }
// int I2.F() { Console.WriteLine( "I2" ); return 0; }

public static void Main() {
Test test = new Test();
I1 i1 = test as I1;
I2 i2 = test as I2;

i1.E += new VD1(test.vd1_i);

//i1.F();
//i2.F();
}
}
 
C

Christof Nordiek

Wiktor Zychla said:
Hi,

suppose there are two interfaces that contain methods with the same
name but different signature:

interface I1 { void F(); }
interface I2 { int F(); }

it is then easy to implement these two interfaces on a single class with
interface prefixes:

class T : I1, I2 {
void I1.F() { ... };
int I2.F() { ... };
}

its obvious.

however, I am stuck trying the same with events:

public delegate void VD1();
public delegate void VD2();

interface I1 { event VD1 E(); }
interface I2 { event VD2 E(); }

following does not work:

class T : I1, I2 {
event VD1 I1.E;
event VD2 I2.E;
}

error CS0071: An explicit interface implementation of an event must use
property syntax.
<snip>

try this:

class T: I1,I2 {
VD1 e1;
VD2 e2;

event VD1 I1.E { add{ e1+= value; } remove { e1-= value;} }
event VD2 I2.E { add{ e2+= value; } remove { e2-= value;} }
}

To fire the events invoke e1 resp. e2.
 
W

Wiktor Zychla [C# MVP]

class T: I1,I2 {
VD1 e1;
VD2 e2;

event VD1 I1.E { add{ e1+= value; } remove { e1-= value;} }
event VD2 I2.E { add{ e2+= value; } remove { e2-= value;} }
}

nice indeed. although this delegate approach does not solve my original
problem, I am glad that at least some solution exists. thanks.
 

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