Type casting vs as operator in C#

131 Views Asked by At

What is the difference between Type casting and as operator in C#. For example in this code:

class LivingThing
{
        public int NumberOfLegs { get; set; }
}
class Parrot : LivingThing
{

}

interface IMover<in T>
{
        void Move(T arg);
}

class Mover<T> : IMover<T>
{
    public void Move(T arg)
    {
       // as operator
       Console.WriteLine("Moving with" + (arg as Parrot).NumberOfLegs + " Legs");
       // Type casting
       Console.WriteLine("Moving with" + (Parrot)arg.NumberOfLegs + " Legs");
    }
}

Why the Type casting is not valid in the second situation and what is the difference of those?

2

There are 2 best solutions below

0
On BEST ANSWER

Well,

  • ((Parrot) arg) cast : either Parrot instance or exception (invalid cast) thrown. Note, that you should cast arg first and only then use NumberOfLegs: Console.WriteLine("Moving with" + ((Parrot)arg).NumberOfLegs + " Legs"); note extra (...)
  • arg as Parrot: either Parrot instance or null (note you can't use as if type is struct and thus can't be null)
  • arg is Parrot: either true if arg can be cast to Parrot or false otherwise

The last case (is) can be used in pattern matching, e.g.

Console.WriteLine($"Moving with {(arg is Parrot parrot ? parrot.NumberOfLegs : 0)} Legs");
0
On

The type casting is invalid because you should do this

 // ((Parrot)arg).NumberOfLegs
 Console.WriteLine("Moving with" + ((Parrot)arg).NumberOfLegs + " Legs");

Difference are :

  • Type Casting (Explicit Casting): (Parrot) if arg is not a Parrot or a type derived from Parrot. It does not perform any safety checks.
  • Operator: The as operator performs a conversion between reference types or nullable types, and it includes a safety check. If the cast is not valid, it returns null rather than throwing an exception. So (arg as Parrot).NumberOfLegs will attempt to convert arg to Parrot, and if arg is not a Parrot, it will return null. If you then try to access NumberOfLegs, you'll get a NullReferenceException.

Note: It's also a good practice to add generic type constraint : https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint