Polymorphism in C# makes no sense
Let's assume such a case:
And for the Car class I have an error
I could use IEngine instead of Engine in Car, which would fix the error. But then I can't use the methods of the Engine class.
I completely don't understand why I can't use Engine since this class implements IEngine.
I can't have different classes implementing ICar and having inside different classes implementing IEngine, they all have to be on the base IEngine.
This is terribly frustrating.
Instead of using interfaces in such cases, I have to get rid of them.
15 Replies
Engine
property in the Car
class is of type Engine
, but the ICar
interface expects a property of type IEngine
. Even though Engine
implements IEngine
, they are not the same type.I know, I understand the error.
But it just doesn't make sense to me. Since
Engine
implements IEngine
, it completely meets its requirements.
Wouldn't it be much more useful if it were truly polymorphic?
I do not understand why in this case it was done this way.If
ICar
was allowed to have a property of type Engine
, then every car
would need to have an Engine
, not just an IEngine
. This would limit the flexibility of your code. For example, you wouldn’t be able to have a Car
with a SuperEngine
(a different class that implements IEngine
).
Basically by having a property of type IEngine
in ICar
. You aren't enforcing any specific type of engine. Take this example: I can specify any engine but then I cannot use methods of this different engines. Like
bugatti.Engine.WorkOnShittyEngine()
. I'm only limited to use things that IEngine provides.
I thinks this is what limit the flexibility of mine code.This is a design choice in the language itself to ensure type safety
It's mostly useful in larger codebases
u can use two interfaces, and explicit interface implementations to get it to work how u want:
that way only if u use it as
ICar
(the not-generic version), u get the IEngine Engine { get; }
property on the API surface,
else u get the Engine Engine { get; }
propertyYou could do this
Then you can use your specific engine inside your class.
And the public facing side is defined by your interface.
That's also a good solution
i first thought of ur solution as well, but that wouldnt work for the brought up example (
bugatti.Engine.WorkOnShittyEngine()
) eitherFair
ICar<TEngine>
could also extend ICar
, so that Car
only has to have ICar<Engine>
on its base type listThe solution is good, although it causes a large code add-on.
Apparently I am used to more flexible languages 😛
Anyway, thank you
The problem is this:
Now you can do:
Oops! Even though your
Car
class has an engine of type Engine
, I managed to assign a ShittyEngine
instance to it.
That's a big problem if your Engine
class has a Start()
method on it, which isn't available on IEngine
/ShittyEngine
. If Car
tries to call this.Engine.Start()
, and I've gone and replaced the engine with a ShittyEngine
, what happens?
And the normal workaround is with explicit interface implementation:
i guess the whole
ICar<TEngine>
wasnt even needed 😂Just get a real car with a proper engine. Don't make a virtual one.
this is only supported for things defined on abstract classes, not interfaces
it is not supported for interfaces because it is a lot of work, and nobody really is interested, and the workaround with explicit implementation works fine
another thing you can do is use a default interface member this removes all of the boilerplate from the implementing classes