3

The real problem comes up with Reflection and assembly patching/hooking. I'll put a simple example to show up my question without being too hard to understand the main problem.

So let's imagine I have these basic classes :

public class Vehicle
{
    public string Name;
    public string Price;

    public void DoSomething()
    {
        Main.Test(this);
    }
}

public class Car : Vehicle
{
    public int Wheels;
    public int Doors;
}

And on the main code I run this up :

public class Main
{
    public void Start()
    {
        Car testCar = new Car()
        {
            Name = "Test Car",
            Price = "4000",
            Wheels = 4,
            Doors = 4
        };

        testCar.DoSomething();
    }

    public static void Test(Vehicle test)
    {
        // Is this allowed ?
        Car helloWorld = (Car) test;
    }   
}

Okay, the question is :

Is that cast allowed (in the static method Test) ? Will I lose the Car properties but keep the Vehicle ones ?

In case it's wrong, is there any other way to do it ?

Thanks.

6
  • "In case it's wrong, is there any other way to do it ?" To do what?
    – Ivan Stoev
    Commented Dec 19, 2015 at 20:07
  • see downcasting: stackoverflow.com/questions/1524197/downcast-and-upcast Commented Dec 19, 2015 at 20:10
  • 2
    Welcome to Stack Overflow. That should be something which is relatively easy to test. So have you tried it? If not, that's kind of a prerequisite to asking a question. If you have, is there a specific problem you're having?
    – ardila
    Commented Dec 19, 2015 at 20:10
  • @IvanStoev To get the object as a Car and not as a Vehicle.
    – Snak
    Commented Dec 19, 2015 at 20:11
  • What if it's a Truck? I mean, imagine you have another class Truck : Vehicle, how do you know that Vehicle test is Car and not Truck or any other Vehicle derived class
    – Ivan Stoev
    Commented Dec 19, 2015 at 20:15

3 Answers 3

5

The cast of Vehicle to Car is allowed only when the object passed in happens to be Car. Otherwise you get an exception.

There is a cast that does not cause exceptions when the type is wrong:

Car car = test as Car;

This will never throw, but when Vehicle is not a Car, variable car would be null. You could add an if condition to test that the cast has succeeded:

Car car = test as Car;
if (car != null) {
    ...
}
Bus bus = test as Bus;
if (bus != null) {
    ...
}
Rv rv = test as Rv;
if (rv != null) {
    ...
}

However, C# offers an even better solution: method overloading lets you avoid casting altogether.

public class Main {
    public static void Test(Car test) {
        ... // This method will be called by Main.Test(this) of a Car
    }
    public static void Test(Bus test) {
        ... // This method will be called by Main.Test(this) of a Bus
    }
    public static void Test(Rv test) {
        ... // This method will be called by Main.Test(this) of an Rv
    }
}

This works, because the compiler knows the exact type of this variable when you make the Main.Test(this) call.

1
  • That's what I was looking for. Thanks for the answer !
    – Snak
    Commented Dec 19, 2015 at 20:19
2

Yes, the cast is allowed, and you will not "lose" any properties. But if Vehicle test is not, in fact, an instance of Car then your cast will throw an InvalidCastException.

1
  • Thanks for the answer !
    – Snak
    Commented Dec 19, 2015 at 20:19
0

Yes, it is allowed. It's named downcasting.

Remember it is possible to check through type introspection to determine whether the type of the referenced object is indeed the one being cast to or a derived type of it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.