44

Ich habe eine generische Klasse, für die ich implizite Typ Casting implementieren möchte. Während es meistens funktioniert, wird es nicht für das Interface-Casting funktionieren. Bei weiteren Untersuchungen stellte ich fest, dass ein Compiler-Fehler vorliegt: "Benutzerdefinierte Konvertierung von der Schnittstelle". Während ich verstehe, dass dies in einigen Fällen erzwungen werden sollte, scheint das, was ich versuche, wie ein legitimer Fall zu sein.impliziter Operator mit Schnittstellen

Hier ist ein Beispiel:

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, es zu benutzen:

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

Kennt jemand eine Abhilfe, oder kann jemand in befriedigender Weise erklären, warum shuouldn't ich in der Lage sein zu werfen interfaceReferenceToBar implizit zu Foo<IBar>, denn in meinem Fall wird es nicht konvertiert, sondern nur in Foo enthalten?

EDIT: Es sieht aus wie Kovarianz könnte Rettung bieten. Hoffen wir, dass die C# 4.0-Spezifikation implizites Casting von Schnittstellentypen mit Kovarianz ermöglicht.

Antwort

46

Der Grund, warum Sie dies nicht tun können, ist, weil es speziell in der Sprache C# Spezifikation verboten ist:

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.

und

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.

Source

+0

Ich verstehe, dass es Teil der ist Spezifikation, implizites Casting einer Schnittstelle sollte in einigen Fällen, aber insgesamt ungültig sein? –

+0

Ich stimme dir zu, ich weiß nicht, warum sie es für alle Fälle ungültig gemacht haben. In diesem Fall können Sie zur Kompilierzeit feststellen, dass die Besetzung gültig ist (sein sollte). –

+3

Ich * glaube *, dass die Einschränkung impliziten Interface-Casting damit zu tun hat, wie COM-Interop implementiert ist. COM verwendet QueryInterface, das von .NET automatisch behandelt wird. Das Zulassen einer impliziten Schnittstellenumsetzung würde stören. – Mark