66

I have a generic class that I'm trying to implement implicit type casting for. While it mostly works, it won't work for interface casting. Upon further investigation, I found that there is a compiler error: "User-defined conversion from interface" that applies. While I understand that this should be enforced in some cases, what I'm trying to do does seem like a legitimate case.

Here's an example:

public class Foo<T> where T : IBar
{
    private readonly T instance;

    public Foo(T instance)
    {
        this.instance = instance;
    }
    public T Instance
    {
        get { return instance; }
    }
    public static implicit operator Foo<T>(T instance)
    {
        return new Foo<T>(instance);
    }
}

Code to use it:

var concreteReferenceToBar = new ConcreteBar();
IBar intefaceReferenceToBar = concreteReferenceToBar;
Foo<ConcreteBar> concreteFooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromInterfaceBar = intefaceReferenceToBar; // doesn't work

Does anyone know a workaround, or can anyone explain in a satisfactory way why I shuouldn't be able to cast interfaceReferenceToBar implicitly to Foo<IBar>, since in my case it is not being converted, but only contained within Foo?

EDIT: It looks like covariance might offer salvation. Let's hope the C# 4.0 specification allows for implicit casting of interface types using covariance.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
Michael Meadows
  • 27,796
  • 4
  • 47
  • 63

1 Answers1

73

The reason you can't do this is because it is specifically forbidden in the C# language specification:

Source: ECMA-334 Section 15.10.4

A class or struct is permitted to declare a conversion from a source type S to a target type T provided all of the following are true:

  • ...
  • Neither S nor T is object or an interface-type.

and

User-defined conversions are not allowed to convert from or to interface-types. In particular, this restriction ensures that no user-defined transformations occur when converting to an interface-type, and that a conversion to an interface-type succeeds only if the object being converted actually implements the specified interface-type.

Charlieface
  • 52,284
  • 6
  • 19
  • 43
Adam Hughes
  • 3,732
  • 24
  • 25
  • 2
    I understand that it's part of the specification, implicit casting of an interface should be invalid in some cases, but in all? – Michael Meadows Sep 27 '08 at 12:59
  • 2
    I agree with you, I don't know why they made it invalid for all cases. In this case you can determine at compile time that the cast is (should be) valid. – Adam Hughes Sep 27 '08 at 13:41
  • 3
    I *believe* that the restriction on implicit interface casting has to do with how COM interop is implemented. COM uses QueryInterface, which .NET handles automatically. Allowing implicit interface conversion would interfere. – Mark Oct 07 '10 at 13:48
  • 4
    @MichaelMeadows, you may be enlightened to read the responses by Adam Houldsworth and Eric Lippert on [my similar question](http://stackoverflow.com/questions/9229928/more-on-implicit-conversion-operators-and-interfaces-in-c-sharp-again) in the C# 4.0 context. – gregsdennis Dec 19 '12 at 18:15
  • 2
    Does it explain why they made this decision anywhere? – Hatchling Feb 04 '17 at 01:58