# Casting

You have probably used casting to convert numeric values from one type to another, i.e.:

``````int a = 5;
double b = a;``````

And

``int c = (int)b;``

What you are actually doing when you cast is transforming a value from one type to another. In the first case, you are taking the value of `a` (5), and converting it to the equivalent double (5.0). If you consider the internal representation of an integer (a 2’s complement binary number) to a double (an IEEE 754 standard representation), we are actually applying a conversion algorithm to the binary representations.

We call the first operation an implicit cast, as we don’t expressly tell the compiler to perform the cast. In contrast, the second assignment is an explicit cast, as we signify the cast by wrapping the type we are casting to in parenthesis before the variable we are casting. We have to perform an explicit cast in the second case, as the conversion has the possibility of losing some precision (i.e. if we cast 7.2 to an integer, it would be truncated to 7). In any case where the conversion may lose precision or possibly throw an error, an explicit cast is required.

## Custom Casting Conversions

We can actually extend the C# language to add additional conversions to provide additional casting operations. Consider if we had `Rectangle` and `Square` structs:

``````/// <summary>A struct representing a rectangle</summary>
public struct Rectangle {

/// <summary>The length of the short side of the rectangle</summary>
public int ShortSideLength;

/// <summary>The length of the long side of the rectangle</summary>
public int LongSideLength;

/// <summary>Constructs a new rectangle</summary>
/// <param name="shortSideLength">The length of the shorter sides of the rectangle</param>
/// <param name="longSideLength">The length of the longer sides of the rectangle</param>
public Rectangle(int shortSideLength, int longSideLength){
ShortSideLength = shortSideLength;
LongSideLength = longSideLength;
}
}

/// <summary>A struct representing a square</summary>
public struct Square {

/// <summary> The length of the square's sides</summary>
public int SideLength;

/// <summary>Constructs a new square</summary>
/// <param name="sideLength">The length of the square's sides</param>
public Square(int sideLength){
SideLength = sideLength;
}
}``````

Since we know that a square is a special case of a rectangle (where all sides are the same length), we might define an implicit casting operator to convert it into a `Rectangle` (this would be placed inside the `Square` struct definition):

``````    /// <summary>Casts the <paramref name="square"/> into a Rectangle</summary>
/// <param name="square">The square to cast</param>
public static implicit operator Rectangle(Square square)
{
return new Rectangle(square.SideLength, square.SideLength);
}``````

Similarly, we might create a cast operator to convert a rectangle to a square. But as this can only happen when the sides of the rectangle are all the same size, it would need to be an explicit cast operator , and throw an exception when that condition is not met (this method is placed in the `Rectangle` struct definition):

``````    /// <summary>Casts the <paramref name="rectangle"/> into a Square</summary>
/// <param name="rectangle">The rectangle to cast</param>
/// <exception cref="System.InvalidCastOperation">The rectangle sides must be equal to cast to a square</exception>
public static explicit operator Square(Rectangle rectangle){
if(rectangle.LongSideLength != rectangle.ShortSideLength) throw new InvalidCastException("The sides of a square must be of equal lengths");
return new Square(rectangle.LongSideLength);
}``````

## Casting and Inheritance

Casting becomes a bit more involved when we consider inheritance. As you saw in the previous discussion of inheritance, we can treat derived classes as the base class, i.e. the code:

``Student sam = new UndergraduateStudent("Sam", "Malone");``

Is actually implicitly casting the undergraduate student “Sam Malone” into a student class. Because an `UndergraduateStudent` is a `Student`, this cast can be implicit. Moreover, we don’t need to define a casting operator - we can always implicitly cast a class to one of its ancestor classes, it’s built into the inheritance mechanism of C#.

Going the other way requires an explicit cast as there is a chance that the `Student` we are casting isn’t an undergraduate, i.e.:

``UndergraduateStudent u = (UndergraduateStudent)sam;``

If we tried to cast `sam` into a graduate student:

``GraduateStudent g = (GraduateStudent)sam;``

The program would throw an `InvalidCastException` when run.

## Casting and Interfaces

Casting interacts similarly with interfaces. A class can be implicitly cast to an interface it implements:

``IJumpable roo = new Kangaroo();``

But must be explicitly cast to convert it back into the class that implemented it:

``Kangaroo k = (Kangaroo)roo;``

And if that cast is illegal, we’ll throw an `InvalidCastException`:

``Car c = (Car)roo;``

## The `as` Operator

When we are casting reference and nullable types, we have an additional casting option - the `as` casting operator.

The `as` operator performs the cast, or evaluates to `null` if the cast fails (instead of throwing an `InvalidCastException`), i.e.:

``````UndergraduateStudent u = sam as UndergraduateStudent; // evaluates to an UndergraduateStudent
Kangaroo k = roo as Kangaroo; // evaluates to a Kangaroo
Car c = roo as Kangaroo; // evaluates to null``````

## The `is` Operator

Rather than performing a cast and catching the exception (or performing a null check when using the `as` operator), it is often useful to know if a cast is possible. This can be checked for with the `is` operator. It evaluates to a boolean, `true` if the cast is possible, `false` if not:

``````sam is UndergraduateStudent; // evaluates to true
sam is GraduateStudent; // evaluates to false
roo is Kangaroo; // evaluates to true
roo is Car; // evaluates to false``````

The `is` operator is commonly used to determine if a cast will succeed before performing it, i.e.:

``````if(sam is UndergraduateStudent)
{
``````if(sam is UndergraduateStudent samAsUGrad)
If the cast is possible, it is performed and the result assigned to the provided variable name (in this case, `samAsUGrad`). This is another example of syntactic sugar .