Ho un semplice metodo factory che fornisce un'istanza di implementazione concreta basata su un parametro di tipo generico fornito. Se le classi concrete ereditano da una classe base astratta comune con un parametro di tipo non posso lanciarle. Il compilatore mi dice Error 2 Cannot convert type 'Car' to 'VehicleBase<T>'
. Funziona bene se sostituisco la classe astratta per un'interfaccia con lo stesso parametro di tipo, o se rimuovo il parametro di tipo generico dalla classe astratta.Impossibile trasmettere il tipo derivato alla classe astratta di base con il parametro type
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();
}
}
}
questo non riesce a compilare il (VehicleBase<T>)new Car()
. Si tratta di un difetto del compilatore o potrebbe essere una decisione deliberata del progetto di trattare le classi astratte e le interfacce con i parametri di tipo in modo diverso?
Come soluzione temporanea, posso sempre rendere la classe astratta implementare un'interfaccia e utilizzarla come valore di ritorno per il mio metodo factory, ma mi piacerebbe comunque sapere perché questo comportamento sta accadendo.
Questa è la soluzione che avevo usato. Grazie per avermi ricordato della varianza in interfacce/delegati - ha senso e risponde alla mia domanda. – dahvyd
Grazie per avermelo ricordato. È fin troppo facile dimenticarsene quando devi solo avere un codice fuori dalla porta –