gwerren.com

Programming notes and tools...

Basic Casting in C#

Mon, 26 Feb 2018 CastC#

In C# you will often find you have a variable of one type that you know is also another type. For example you may have an Animal variable that you know is actually a Dog and you want to ask it to bark. Alternatively you may have an Animal variable and not know what type of animal it is but if it is a Dog you want to ask it to bark.

This switching between types is called casting. There are two basic ways of casting in C#.

var myDog = (Dog)myAnimal;

In this example we cast the variable called myAnimal to a Dog by putting the type Dog in brackets before the variable. This form of casting will throw an exception if the variable myAnimal cannot be cast to a Dog.

var myDog = myAnimal as Dog;

In this example we cast myAnimal to a Dog by putting "as Dog" after it. This will attempt to cast myAnimal to a Dog and if it fails, rather than throwing an exception will set myDog to null. This is useful in the case where you are not sure what type of animal myAnimal is but if it is a Dog you want it to bark, you can cast like this then check for null before asking myDog to bark.

Note that the "as" form of casting can only be used on reference types and nullable value types as it needs to be able to create a null value if the cast is not possible.

To complement "as" there is also an "is" command. This allows you to check if a variable can be cast to a particular type without actually performing the cast as follows:

var isDog = myAnimal is Dog;

Picking the Right Cast

I often see code like the following:

var myDog = myAnimal as Dog;
myDog.Bark();

This code uses the "as" method of casting to get a Dog but then assumes that myDog will not be null. If myAnimal cannot be cast to a Dog then the second line where we call Bark() will throw a null reference exception. As discussed in my post on failing early this will mask the source of the error when you look at an exception thrown here. There are two things we could do here to make this code better.

If we believe myAnimal will always be a Dog then we could use the following code. This will mean that if for some reason myAnimal is not a Dog we will get an invalid cast exception from the first line which is far better. It also tells anyone reading the code later that we expect myAnimal to always be a Dog at this point in the code.

var myDog = (Dog)myAnimal;
myDog.Bark();

If we are not sure what type myAnimal actually is then we could use the following code.

var myDog = myAnimal as Dog;
if (myDog != null)
    myDog.Bark();

Here we attempt to cast to a Dog and then check to see if the cast was successful before barking.