tags:

views:

3078

answers:

4

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

A: 

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.

BC
+1  A: 

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.

jpalecek
I've scoped the original question to C#, so your answer is no longer relevant. Sorry.
Jay Bazuzi
+3  A: 

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.

Steve Rowe
+1  A: 

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".)

Eddie
What about "is": if(meowAnimal is Dog) { Dog d = (Dog)meowAnimal }
Glytzhkof
You can also use the "is" keyword to avoid casting exceptions.
Eddie