implicit operator using interfaces

28,256

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.

Share:
28,256
Michael Meadows
Author by

Michael Meadows

I do cool stuff using Microsoft technology: Azure Service Fabric .Net Core

Updated on March 22, 2021

Comments

  • Michael Meadows
    Michael Meadows about 3 years

    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.