Tengo un método de fábrica simple que proporciona una instancia de implementación concreta basada en un parámetro de tipo genérico proporcionado. Si las clases concretas heredan de una clase base abstracta común con un parámetro de tipo, no puedo convertirlas. El compilador me dice Error 2 Cannot convert type 'Car' to 'VehicleBase<T>'
. Funciona bien si sustituyo la clase abstracta por una interfaz con el mismo parámetro de tipo, o si elimino el parámetro de tipo genérico de la clase abstracta.No se puede convertir el tipo derivado a la clase abstracta base con el parámetro de tipo
interface IWheel
{
}
class CarWheel : IWheel
{
}
abstract class VehicleBase<T>
{
}
class Car : VehicleBase<CarWheel>
{
}
class VehicleFactory
{
public static VehicleBase<T> GetNew<T>()
{
if (typeof(T) == typeof(CarWheel))
{
return (VehicleBase<T>)new Car();
}
else
{
throw new NotSupportedException();
}
}
}
Esta falla al compilar en (VehicleBase<T>)new Car()
. ¿Es esto un defecto del compilador, o podría ser una decisión de diseño deliberada tratar las clases abstractas y las interfaces con los parámetros de tipo de forma diferente?
Como solución alternativa siempre puedo hacer que la clase abstracta implemente una interfaz y usar esto como el valor de retorno para mi método de fábrica, pero aún me gustaría saber por qué ocurre este comportamiento.
Esta es la solución que había utilizado. Sin embargo, gracias por recordarme sobre la varianza en las interfaces/delegados, tiene sentido y responde mi pregunta. – dahvyd
Gracias por recordarme. Es demasiado fácil olvidarlo cuando solo tienes que sacar un código de la puerta –