61 votes

opérateur implicite utilisant des interfaces

J'ai une classe générique pour laquelle j'essaie d'implémenter un casting de type implicite. Bien que cela fonctionne en général, cela ne fonctionne pas pour le casting d'interface. Après une enquête plus approfondie, j'ai découvert qu'il y a une erreur de compilation : "Conversion définie par l'utilisateur à partir d'une interface" qui s'applique. Bien que je comprenne que cela devrait être appliqué dans certains cas, ce que j'essaie de faire semble être un cas légitime.

Voici un exemple :

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 pour l'utiliser :

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

Quelqu'un connaît-il une solution de contournement ou peut-il expliquer de manière satisfaisante pourquoi je ne devrais pas être en mesure de faire des castings ? interfaceReferenceToBar implicitement à Foo<IBar> puisque, dans mon cas, il n'est pas converti, mais seulement contenu dans Foo ?

EDIT : On dirait que la covariance pourrait offrir le salut. Espérons que la spécification C# 4.0 permette le casting implicite des types d'interface en utilisant la covariance.

68voto

Adam Hughes Points 2402

La raison pour laquelle vous ne pouvez pas faire cela est que cela est spécifiquement interdit dans les spécifications du langage C# :

Source : ECMA-334 Section 15.10.4

Une classe ou une structure est autorisée à déclarer une conversion d'un type source source S vers un type cible T à condition que toutes les que toutes les conditions suivantes soient remplies :

  • ...
  • Ni S ni T ne sont object ou un interface-type .

et

Les conversions définies par l'utilisateur ne sont pas autorisées à convertir de ou vers types d'interface . En particulier, cette restriction garantit qu'aucune transformations définies par l'utilisateur ne se produisent lors de la conversion en un interface-type , et qu'une conversion en un interface-type ne réussit que si le objet converti est effectivement implémente l'objet spécifié interface-type .

1 votes

Je comprends que cela fait partie des spécifications, le casting implicite d'une interface devrait être invalide dans certains cas, mais dans tous ?

1 votes

Je suis d'accord avec vous, je ne sais pas pourquoi ils l'ont rendu invalide pour tous les cas. Dans ce cas, vous pouvez déterminer au moment de la compilation que le cast est (devrait être) valide.

3 votes

I croire que la restriction sur le casting implicite d'interface a à voir avec la façon dont COM interop est implémenté. COM utilise QueryInterface, que .NET gère automatiquement. Autoriser la conversion d'interface implicite interférerait.

0voto

hemme Points 878

Adam a raison, il n'y a pas de moyen direct de faire un user-cast depuis ou vers des interfaces.

Quoi qu'il en soit, j'ai récemment rencontré un problème similaire et je l'ai résolu en créant un proxy qui appelle les méthodes de l'interface par réflexion. Vous pouvez trouver un exemple documenté dans mon article " Interfaces : la procuration l'emporte 1-0 sur le moulage ".

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X