I have the following code which doesn't compile. I can't figure out why. Can someone please help?
var mercedes = new Mercedes().WithEngine(new LargeEngine());
var volkswagen = new Volkswagen().WithEngine(new SmallEngine());
public class Mercedes : Car<LargeEngine>
{
}
public class Volkswagen: Car<SmallEngine>
{
}
public class Engine
{
}
public class LargeEngine : Engine
{
}
public class SmallEngine : Engine
{
}
public class Car<T> where T : Engine
{
internal T? Engine { get; set; }
}
public static class ExtensionMethods
{
public static TCar WithEngine<TCar>(this TCar car, Engine engine)
where TCar : Car<Engine>
{
car.Engine = engine;
return car;
}
}
The code above doesn't compile with the error:
The type 'Mercedes' cannot be used as type parameter 'TCar' in the generic type or method 'ExtensionMethods.WithConfiguration(TCar, Engine)'. There is no implicit reference conversion from 'Mercedes' to 'Car<Engine>'
What I understand is that 'Mercedes' type cannot be casted implicitly into 'Car<Engine>' type. But I also cannot figure out a way to cast it explicitly.
Thanks!
Modify the definition of the WithEngine extension method to take a generic type parameter that is constrained to the Car class, where T is a type parameter that is derived from the Engine class.
public static class ExtensionMethods
{
public static TCar WithEngine<TCar, TEngine>(this TCar car, TEngine engine)
where TCar : Car<TEngine>
where TEngine : Engine
{
car.Engine = engine;
return car;
}
}
Car<LargeEngine>
does not inherit from Car<Engine>
, and cannot be implicitly converted to it.
Imagine if generic types did implement inheritance like this. Then we would be able to write the following code:
List<LargeEngine> largeEngines = new List<LargeEngine>();
List<Engine> allEngines = largeEngines;
// Uh-oh - this allows us to add a small engine to the list
allEngines.Add(new SmallEngine());
// The first item in the list is a SmallEngine, not a LargeEngine!
// What should this line do?
LargeEngine x = largeEngines[0];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.