C# Casting

Summary: in this tutorial, you’ll learn about the C# casting including upcasting and downcasting.

Introduction to C# casting

C# is a statically-typed programming language. It means that after you declare a variable, you cannot redeclare it. Also, you cannot reassign a value of another type to the variable unless that type is implicitly compatible with the variable’s type.

An object reference can be:

  • Implicitly upcast to a base class reference. An upcast always succeeds.
  • Explicitly downcast to a subclass reference. A downcast only succeeds if the objects are compatible types.

Upcasting

An upcast creates a base class reference from a subclass reference. For example:

class Person
{
    public string Name { get; set; }
}

class Employee: Person
{
    public string JobTitle { get; set; }
}Code language: C# (cs)
var employee = new Employee()
{
    Name = "John Doe",
    JobTitle = "C# Developer"
};

Person person = employee;Code language: C# (cs)

In this example:

  • First, define the Employee class that inherits from the Person class. The Person class is a base class and the Employee class is a subclass.
  • Second, create a new instance of the Employee class and assign it to the employee variable.
  • Third, assign the object referenced by the employee variable to a reference of the Person class.

After upcasting, the variable person still references the same Employee‘s object. Both employee and person variable reference the same Employee‘s object. The object itself does not change.

Although the person and employee variables refer to the same object, the person has a more restrictive view on that object. For example, it can only access the Name property but cannot access the JobTitle property of the object.

The following statement will cause a compile-time error:

person.JobTitle;Code language: C# (cs)

Error:

'Person' does not contain a definition for 'JobTitle'...Code language: plaintext (plaintext)

Downcasting

A downcast operation creates a subclass reference from a base class reference. A downcast requires a cast expression with the following syntax:

(T)ECode language: C# (cs)

The cast expression explicitly converts the result of the expression (E) to the type T. If no explicit conversion exists from the type of E to type T, the compiler will raise an error.

Also, at runtime, the explicit conversion might fail and the cast expression might throw an exception.

The following example illustrates the downcasting:

var employee = new Employee()
{
    Name = "John Doe",
    JobTitle = "C# Developer"
};

Person person = employee; // upcast

Employee employee2 = (Employee)person; // downcast

Console.WriteLine(employee2.Name);
Console.WriteLine(employee2.JobTitle);Code language: C# (cs)

In this example, the downcast operation explicitly converts the object referenced by the person reference to the employee2.

Since the employee2 variable refers to the Employee object, it can access all properties of the Employee‘s object.

The following defines the Candidate class that inherits from the Person class:

class Person
{
    public string Name { get; set; }
}

class Employee : Person
{
    public string JobTitle { get; set; }
}

class Candidate : Person
{

}Code language: C# (cs)

The following downcast will fail at runtime:

var employee = new Employee()
{
    Name     = "John Doe",
    JobTitle = "C# Developer"
};

Person person = employee;                // upcast
Candidate candidate = (Candidate)person; // downcast fail at runtimeCode language: C# (cs)

In this example, the person variable references an instance of the Employee class. However, we cast it as an instance fo the Candidate class, which is not an instance of the Employee class.

If you run the program, you’ll get the following exception:

System.InvalidCastException: 'Unable to cast object of type 'Employee' to type 'Candidate'.'Code language: plaintext (plaintext)

The as operator

If a downcast fails, it’ll throw an exception at runtime. If you don’t want this behavior, you can use the as operator.

The as operator performs a downcast that evaluates to null rather than throwing an exception if the downcast fails. This allows you to subsequentially check whether the result of the downcast is null or not. For example:

var employee = new Employee()
{
    Name = "John Doe",
    JobTitle = "C# Developer"
};

Person person = employee;// upcast

Candidate candidate = person as Candidate;
if (candidate != null)
{
    Console.WriteLine(candidate.Name);
}Code language: C# (cs)

In this example, the downcast fails. Therefore, the candidate variable is null. Then, we check whether the candidate is null or not before displaying its name property to the console.

Summary

  • An object reference can be implicitly upcast to a base class reference. An upcast always succeeds.
  • An object reference can also be explicitly downcast to a subclass reference. A downcast succeeds only if the object is compatible typed.
  • Use the as operator to perform a downcast that evaluates to null rather than throwing an exception.
Was this tutorial helpful ?