Perché questo tipo di conversione implicita in C # fallire?
-
22-09-2019 - |
Domanda
Sfondo:
Supponiamo che io ho la seguente classe:
class Wrapped<T> : IDisposable
{
public Wrapped(T obj) { /* ... */ }
public static implicit operator Wrapped<T>(T obj)
{
return new Wrapped<T>(obj);
}
public void Dispose() { /* ... */ }
}
Come si può vedere, fornisce un operatore tipo di conversione implicita per T
→ Wrapped<T>
. In definitiva, mi piacerebbe essere in grado di utilizzare questa classe come segue:
interface IX { /* ... */ }
class X : IX { /* ... */ }
...
IX plainIX = new X();
using (Wrapped<IX> wrappedIX = plainIX)
{
/* ... */
}
Problema:
Tuttavia, la conversione di tipo nella clausola using
precedente non riesce. Mentre posso assegnare un new X()
direttamente a wrappedIX
, non mi è permesso di assegnare qualche cosa di tipo IX
ad esso. Il compilatore si lamenta con il seguente errore:
errore di compilazione CS0266: Impossibile convertire implicitamente il tipo 'IX' a 'Wrapped
'. Esiste una CONVERSIONE esplicito (che le manca un cast?)
Non capisco questo. Qual è il problema qui?
Soluzione
Credo che sia perché IX
è un'interfaccia. Il compilatore pensa che forse un valore di tipo IX
potrebbe già essere derivato da Wrapped<IX>
(anche se Wrapped<T>
è sigillato) in modo che non utilizza la conversione.
I dettagli sono piuttosto complicato, nelle sezioni 6.4.3 e 6.4.4 delle specifiche C # 3.0. Fondamentalmente perché IX
è un'interfaccia, non è "comprendeva" da qualsiasi tipo, che significa un passo avanti in 6.4.4 fallisce.
Vi suggerisco di creare un tipo non generico Wrapped
con questo metodo:
public static Wrapped<T> Of<T>(T item)
{
return new Wrapped<T>(item);
}
Poi si può solo scrivere:
using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))
Fondamentalmente conversioni possono essere un po 'complicato per vari motivi -. Metodi semplici sono generalmente più facili da comprendere, IMO