Es bastante desconcertante descubrir que la restricción de genéricos no se puede convertir en su tipo derivado.¿Por qué la restricción de genéricos no se puede convertir en su tipo derivado?
Digamos que tengo el siguiente código:
public abstract class BaseClass
{
public int Version
{ get { return 1; } }
public string FixString { get; set; }
public BaseClass()
{
FixString = "hello";
}
public virtual int GetBaseVersion()
{
return Version;
}
}
public class DeriveClass: BaseClass
{
public new int Version
{ get { return 2; } }
}
Y adivina qué, este método devolverá un error de compilación:
public void FreeConversion<T>(T baseClass)
{
if(baseClass.GetType()==typeof(DeriveClass)
var derivedMe = (DeriveClass)baseClass;
}
tendría que emitir el baseClass
a object
primero antes de que yo puede convertirlo a DerivedClass
, es decir,
public void FreeConversion<T>(T baseClass)
{
if(baseClass.GetType()==typeof(DeriveClass)
var derivedMe = (DeriveClass)((object)baseClass);
}
Me parece bastante feo. ¿Por qué esto es así?
¿Por qué el compilador no puede saberlo? Pensé que debería saber porque explícitamente especifico que 'DeriveClass' es una clase heredada para' BaseClass' – Graviton
@Ngu: No, no es así. Usted * prueba * para ver * si * 'T' es de tipo' DeriveClass', y luego - * independientemente de la prueba * - intenta convertir explícitamente 'T' en' DeriveClass'. Recuerde, el compilador * no * ejecuta * su código, simplemente * compila *. Lo que podrías hacer es convertir con una cláusula 'as' en lugar de un molde explícito. 'baseClass as DeriveClass' devolverá la instancia como' DeriveClass' si es posible, y 'null' de lo contrario, pero si comprueba que es posible primero (como lo hace ahora) sabe (aunque su código no) que lo hará nunca ser 'nulo'. –
@Ngu ¡El compilador no puede saber porque nadie puede saberlo! Cuando se crea la plantilla no hay nada que decir que solo recibirá un parámetro de BaseClass y ciertamente nada que decir que será un valor de DerivedClass. No hay nada que impida que alguien llame 'FreeConversion (42)' por ejemplo. La única excepción es un método miembro de una plantilla restringida derivada de su propio parámetro (realmente útil en algunos casos). –