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:
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)