71

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.

0

1 Answer 1

77

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.

Sign up to request clarification or add additional context in comments.

6 Comments

I understand that it's part of the specification, implicit casting of an interface should be invalid in some cases, but in all?
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.
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.
@MichaelMeadows, you may be enlightened to read the responses by Adam Houldsworth and Eric Lippert on my similar question in the C# 4.0 context.
Does it explain why they made this decision anywhere?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.