.NET September 14, 2020
5 min read

The is and as Operators in C#

When we deal with casting, there are situations where an Exception can be thrown. For example, if the type of the object in memory does not match the cast, the runtime will throw a System.InvalidCastException. For example:

class Program
{
    static void Main(string[] args)
    {
        Object obj = new Car();

        var bus = ((Bus)obj); // This will throw a System.InvalidCastException;
        var b = (int) obj; // This will throw a System.InvalidCastException;
    }
}

This code will compile but will throw an exception at runtime. To avoid this kind of error, we can use the is and as operators which are provided by C# and can help us to perform casting operations in a more elegant way.

The is Operator

The is operator is used to checking if the run-time type of an object is compatible with a given type or not. The result of the validation will return a boolean value (true or false), and the is operator never throws an exception. Example:

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person();
        
        Boolean b1 = (person is Person); // this will return true;
        Boolean b2 = (person is Employee); // this will return false;
    }
}

When using the is operator to check if the object matches with a specific type, will not throw an exception in case of the type be different. Example:

class Program
{
    static void Main(string[] args)
    {
        Object obj = new Car();
        
        if (obj is Bus)
            Console.WriteLine("Entered here - Bus"); // This will not be printed and will not throw an exception;
        if (obj is 0)
            Console.WriteLine("Entered here - 0"); // This will not be printed and will not throw an exception;
        if (obj is "value")
            Console.WriteLine("Entered here - value"); // This will not be printed and will not throw an exception;
        if (obj is Car)
            Console.WriteLine("Entered here - Car"); // This will be printed;
    }
}

If the reference of the object is null, the operator is it will always return false, because there is no object available to check its type.

Those are the specification of the is operator:

  • Used to check if the run-time type of an object is compatible with the given type or not
  • Is of boolean type
  • Returns true if the given object is of the same type
  • Returns false if the given object is not of the same type
  • Used for only reference, boxing, and unboxing conversions

One problem of the is operator is when you check it and after that also cast to the instance of the type. The problem of doing that is because ‘behind the scene’ the isoperator uses a cast to make its determination. On the example below, there are two separated cast, the first one is on the is and the second is on the explicit cast:

class Program
{
    static void Main(string[] args)
    {
        Object obj = new Car();

        if (obj is Car) // The first cast to check
        {
            ((Car) obj).Run(); // The second cast - the explicit cast
        }
    }
}

It’s not necessary to cast twice if we do not need to do it. So a better approach for this situation is to use the is operator with a variable, for example:

class Program
{
    static void Main(string[] args)
    {
        Object obj = new Car();

        if (obj is Car car)
        {
            car.Run();
        }
    }
}

On this example, only one cast is happening. Another good way to do it is by using the as operator.

The as Operator

The as operator is used to explicitly convert a value to a given reference type or nullable type. The as operator never throws an exception, and if the conversion is not possible, it will return null. Example:

class Program
{
    static void Main(string[] args)
    {
        Object obj = new Car();
        Car car = obj as Car;
        if (car != null)
            Console.WriteLine("Entered here"); // This will be printed;

        Object obj2 = new Bus();
        Car car2 = obj2 as Car;
        if (car2 != null)
            Console.WriteLine("Entered here"); // This will not be printed;
    }
}

In this example, we only have one cast on each block of code, and also this approach allows you to avoid any exceptions that may occur at execution time.

Those are the specification of the as operator:

  • Used to perform a conversion between compatible reference types or nullable types
  • Is not of boolean type
  • Returns the object when they are compatible with the given type
  • Return null if the conversion is not possible
  • Used only for nullable, reference and boxing conversion

Conclusion

The is and as operators are two good ways of doing the cast of the objects, and they also help us to avoid exception in case of some failure during the cast. Just need to be careful that sometimes instead of using casting, can be better to use polymorphism to solve some problem, for example, if you are doing multiple checks for different types, doing a lot of casting and then calling methods of those types, you should consider if using polymorphic could be better.


References

The Is and As Operators in C#

Is vs As operator keyword in C#

IS vs AS Operators in C#

Microsoft Documentation — Expressions

Is And As Operators In C# — Code with Shadman