"cannot implement an interface error" when the interface and concrete are in different projects

This compiles:

public interface IMyInterface { event Action<dynamic> OnSomeEvent; } class MyInterface : IMyInterface { public event Action<dynamic> OnSomeEvent; } 

But when I separate the interface and implementation into different projects, I get:

Accessor 'TestProject2.MyInterface.OnSomeEvent.remove' cannot implement the interface 'InterfaceNamespace.IMyInterface.remove_OnSomeEvent (System.Action)' for type 'TestProject2.MyInterface'. Use an explicit implementation interface.

This only happens with a dynamic parameter ...

+46
c # events dynamic
May 8 '11 at 8:41
source share
3 answers

Good booty. This seems like a bug in the C # compiler - I will ping Eric Lippert to see what he thinks. ( dynamic may be a little complicated, it may well be a completely good, but non-obvious reason for this error.)

EDIT: The code below does not seem to work. I could have sworn that I had this this morning ... I am very confused about what is happening. According to Simon, the code crashes with the message that it is not supported by the language.

Note that if you use an explicit interface implementation, it seems to just compile:

 // Doesn't actually compile - see edit above class MyInterface : IMyInterface { private Action<dynamic> foo; event Action<dynamic> IMyInterface.OnSomeEvent { // TODO (potentially): thread safety add { foo += value; } remove { foo -= value; } } } 



EDIT: The rest of this answer is still worth ...

Please note that you cannot specify a field event as an explicitly implemented event, i.e. this does not work:

 event Action<dynamic> IMyInterface.OnSomeEvent; 

The following error message appears:

Test.cs (15.39): error CS0071: Explicit interface implemenation for an event should use event access syntax

And if you just try to change the syntax for accessing the event, you will get the same error as the original code.

Note that changing an event to a property works fine with an implementation implemented automatically.

+30
May 8 '11 at 8:53
source share
โ€” -

Thank you for posting this question, and thanks to John for submitting it. I put this in line for an investigation of one of our testers specializing in "dynamic". Let's see if we can understand what is happening here. It certainly smells like a mistake.

In the future, consider publishing such things on Connect.microsoft.com; which gets to testers faster and gives us the best mechanism to get more information about the problem.

+9
May 9 '11 at 17:23
source share

This answer is to clarify my thoughts on this interesting issue. Not a real answer, but a contribution to the whole discussion, which is too small for a normal comment .

I checked a few things about this interface:

 namespace DifferentAssemblyNamespace { public interface IBar { event Action<dynamic> OnSomeEvent; } } 

and its implementation:

 // implicit interface implementation // generates compile error "Explicit interface implementation" public class Foo1 : IBar { private Action<dynamic> foo; public event Action<dynamic> OnSomeEvent { add { foo += value; } remove { foo -= value; } } } // implicit interface implementation // generates compile error "Not supported by the language" public class Foo2 : IBar { private Action<dynamic> foo; event Action<dynamic> IBar.OnSomeEvent { add { foo += value; } remove { foo -= value; } } } 

will never work , it seems that one rule excludes another necessary rule.

but .. if we call generics for reference and use the Type parameter instead of using dynamic just like:

 namespace DifferentAssemblyNamespace { public interface IGenericBar<T> { event Action<T> OnSomeEvent; } } 

and its implementation.

 // implicit interface implementation public class Foo3<T> : IGenericBar<T> { private Action<T> foo; event Action<T> IGenericBar<T>.OnSomeEvent { add { foo += value; } remove { foo -= value; } } } 

for some reason we can build (as it should) and run:

 /** does build **/ IGenericBar<dynamic> f = new Foo3<dynamic>(); f.OnSomeEvent += new Action<dynamic>(f_OnSomeEvent); 

it looks like the type parameter is doing something extra that the compiler is happy with.

I'm not sure what is going on, so I would like to know too.

speculation, very hypothetical (maybe shit)

but at the moment I'm putting my two cents on type comparisons should be using add / remove accessories in a linked list that contains the purpose / methods of the event.

I bet that the compiler crashes into a problem that cannot guarantee that the dynamic is in the external assembly, so it cannot determine whether an item is in the list or not, which is necessary to add or remove. (Therefore, an explicit implementation of the interface)

We all know that these are just some of the attributes of an object, but it still seems like it needs an extra step when some strong type is guaranteed, and that is what T does at compile time.

/ guess very hypothetical (maybe shit)

+2
May 09 '11 at 19:24
source share



All Articles