Pourquoi cette conversion de type implicite en C # échoué?
-
22-09-2019 - |
Question
Arrière-plan:
Supposons que j'ai la classe suivante:
class Wrapped<T> : IDisposable
{
public Wrapped(T obj) { /* ... */ }
public static implicit operator Wrapped<T>(T obj)
{
return new Wrapped<T>(obj);
}
public void Dispose() { /* ... */ }
}
Comme vous pouvez le voir, il fournit un opérateur de conversion de type implicite pour T
→ Wrapped<T>
. En fin de compte, je voudrais être en mesure d'utiliser cette classe comme suit:
interface IX { /* ... */ }
class X : IX { /* ... */ }
...
IX plainIX = new X();
using (Wrapped<IX> wrappedIX = plainIX)
{
/* ... */
}
Problème:
Toutefois, la conversion de type dans la clause using
ci-dessus échoue. Bien que je puisse attribuer un new X()
directement à wrappedIX
, je ne suis pas autorisé à céder quoi que ce soit de type IX
à elle. Le compilateur se plaindra avec l'erreur suivante:
erreur du compilateur CS0266: Impossible de convertir implicitement le type 'IX' à 'Enveloppé
'. Il existe une ONVERSION explicite (vous manque un casting?)
Je ne comprends pas. Quel est le problème ici?
La solution
Je crois qu'il est parce que IX
est une interface. Le compilateur pense que peut-être pourrait déjà être dérivé d'une valeur de type IX
de Wrapped<IX>
(même si Wrapped<T>
est scellé) de sorte qu'il n'utilise pas la conversion.
Les détails sont assez compliquées, dans les sections 6.4.3 et 6.4.4 de la spécification C # 3.0. Fondamentalement parce que IX
est une interface, il ne « entouré par » tous les types, ce qui signifie une étape ultérieure 6.4.4 échoue.
Je vous suggère de créer un type non générique Wrapped
avec cette méthode:
public static Wrapped<T> Of<T>(T item)
{
return new Wrapped<T>(item);
}
Ensuite, vous pouvez simplement écrire:
using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))
Fondamentalement conversions peuvent être un peu difficile pour diverses raisons -. Méthodes simples sont généralement plus faciles à comprendre, l'OMI