¿Por qué esta conversión implícita en C # fallar?
-
22-09-2019 - |
Pregunta
Antecedentes:
Vamos a suponer que tengo la siguiente clase:
class Wrapped<T> : IDisposable
{
public Wrapped(T obj) { /* ... */ }
public static implicit operator Wrapped<T>(T obj)
{
return new Wrapped<T>(obj);
}
public void Dispose() { /* ... */ }
}
Como se puede ver, se proporciona un operador de conversión de tipo implícito para T
→ Wrapped<T>
. En última instancia, me gustaría ser capaz de utilizar esta clase de la siguiente manera:
interface IX { /* ... */ }
class X : IX { /* ... */ }
...
IX plainIX = new X();
using (Wrapped<IX> wrappedIX = plainIX)
{
/* ... */
}
Problema:
Sin embargo, la conversión de tipo en la cláusula using
anterior falla. Mientras que puedo asignar un new X()
directamente a wrappedIX
, no se me permite asignar cualquier tipo de IX
a ella. El compilador se quejará con el siguiente error:
compilador CS0266 de error: No se puede convertir implícitamente el tipo 'IX' a 'Envuelto
'. Existe una CONVERSIÓN explícita (¿falta un yeso?)
No entiendo esto. ¿Cuál es el problema aquí?
Solución
Creo que es porque IX
es una interfaz. El compilador piensa que tal vez un valor de tipo IX
ya se podría derivar de Wrapped<IX>
(incluso si Wrapped<T>
está sellado) para que no se utilice la conversión.
Los detalles son bastante complicados, en las secciones 6.4.3 y 6.4.4 de la especificación C # 3.0. Básicamente porque IX
es una interfaz, que no está "abarcada por" cualquier tipo, lo que significa un paso adelante en 6.4.4 falla.
Sugiero crear un Wrapped
tipo no genérico con este método:
public static Wrapped<T> Of<T>(T item)
{
return new Wrapped<T>(item);
}
A continuación, sólo se puede escribir:
using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))
Básicamente conversiones puede ser un poco difícil por varias razones -. Métodos simples son generalmente más fáciles de entender, la OMI