5

Why does this conversion not work?

public interface IMyInterface
{
}

public interface IMyInterface2 : IMyInterface
{
}

public class MyContainer<T> where T : IMyInterface
{
     public T MyImpl {get; private set;}
     public MyContainer()
     {
          MyImpl = Create<T>();
     }
     public static implicit T (MyContainer<T> myContainer)
     {
        return myContainer.MyImpl;
     }
}

When I use my class it causes a compile time error:

IMyInterface2 myImpl = new MyContainer<IMyInterface2>();

Cannot convert from MyContainer<IMyInterface2> to IMyInterface2...hmmmm

Adam Driscoll
  • 9,395
  • 9
  • 61
  • 104
  • 2
    I ran into this same problem. It's not a bug in the compiler, but rather, a documented part of the spec. See http://stackoverflow.com/questions/1208796/c-compiler-bug-why-doesnt-this-implicit-user-defined-conversion-compile A respected member of the C# compiler team added an answer to the above question and added, "this is a very, very confusing part of the spec". – Judah Gabriel Himango Jan 23 '10 at 21:39
  • Thanks for the follow up. That's helpful. I didn't think it was a bug but possibly something I didn't understand about the spec, which it turned out to be. Kind of sucks because it would have made my code much cleaner...oh well. I guess I'll just write my own language :P – Adam Driscoll Jan 23 '10 at 21:43
  • I hear you. I have some structs like NonNull and Maybe, and converting to/from these types would be much cleaner had the spec allowed for this scenario. I wish they'd change the spec; I'd rather have the possibility of less-inexpensive conversions and enable this implicit conversion scenario. – Judah Gabriel Himango Jan 23 '10 at 21:52

2 Answers2

5

You cannot define an implicit conversion to an interface. Therefore your generic implicit operation is not going to be valid for interfaces. See blackwasp.co.uk

You may not create operators that convert a class to a defined interface. If conversion to an interface is required, the class must implement the interface.

You may just have to end up writing the following, without implicit magic:

IMyInterface2 myImpl = new MyContainer<IMyInterface2>().MyImpl;
Greg
  • 23,155
  • 11
  • 57
  • 79
3

It has to do with the fact that IMyInterface2 is an interface, if you replace it with

public class MyClass2 : IMyInterface
{
}

it does work.

Here is the reference, 10.9.3

H H
  • 263,252
  • 30
  • 330
  • 514