In C#, when I have an interface and several concrete implementations, can I cast the interface to a concrete type or is concrete type cast to interface?
What are the rules in this case?
Thanks
In C#, when I have an interface and several concrete implementations, can I cast the interface to a concrete type or is concrete type cast to interface?
What are the rules in this case?
Thanks
Both are valid, considering it's a logical cast. Many times, your interface consumers don't have access to the concrete classes which is one major reason to have an interface in the first place.
If you're talking about Java (but rules for other languages are similar), it is like this:
You can (down)cast an interface to a concrete implementation, iff the reference you cast actually is a reference to the specific concrete implementation. That means
Vehicle v=new Car();
(Car)v // this is OK
(Bus)v // this is not
The error manifests itself as ClassCastException
in Java.
You can upcast a concrete implementation of an interface to the interface freely.
In most languages you can cast both directions. If you have a concrete class, you can cast it to the interface. If you have an interface, it is possible to cast to the concrete class.
Generally, you only want to go in the first direction. The reason being that you shouldn't know what the concrete class is when you have only a pointer to the interface. If you are passing something around as an interface, you should be able to do whatever you need to from that interface. If you find yourself needing to use parts of the concrete object not on the interface, you have a design problem that should be fixed instead of casting.
Both directions are allowed in Java and C#. Downcasting needs an explicit cast and may throw an Exception if the object is not of the correct type. Upcasting, however, needs no explicit cast and is always safe to do.
That is, assuming you have public interface Animal
and two implementations of this interface
, Cat
and Dog
....
Animal meowAnimal = new Cat(); // No cast required
Animal barkAnimal = new Dog(); // No cast required
Cat myCat = (Cat) meowAnimal; // Explicit cast needed
Dog myDog = (Dog) barkAnimal; // Explicit cast needed
Dog myPet = (Dog) meowAnimal; // Will compile but throws an Exception
and you'll want a try
/ catch
around the explicit casts. In C# you have the useful as
keyword:
Dog myDog = barkAnimal as Dog;
Dog myPet = meowAnimal as Dog;
No exception will be thrown, and myDog will be nonNull and myPet will be null. Java does not have an equivalent keyword although you can always use if (meowAnimal instanceof Dog)
tests to keep type safety. (I would guess that the "as
" keyword generates bytecode that does the if, assigning null of the is
fails. But perhaps .NET has a bytecode instruction that does the equivalent of "as
".)