implicit operator using interfaces
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.
Michael Meadows
I do cool stuff using Microsoft technology: Azure Service Fabric .Net Core
Updated on March 22, 2021Comments
-
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 toFoo<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.