Since C# is a type-safe language, an expression of a particular type can only be assigned to a compatible type; this often necessitates type conversion. The C# language offers various methods and operators to facilitate this conversion or checking the datatype of the expression. C# provides various operators (e.g.
as keyword or cast operator) to convert an expression from one type into another type; it also provide
is operator to check if an expression is of some specific type or not.
The knowledge of these operators is essential for any C# programmer, as they are routinely needed by the developers.
In this post we will see the differences between as, is and cast operators.
IS OPERATOR
First, we consider about
is operator. It is a binary operator which takes expression as left operand and a datatype as right operand. It checks if the expression is of the datatype given in the right operand. If true, then it returns True else returns False. Now, consider the following example:
class Program
{
static void Main(string[] args)
{
int number = 42;
Console.WriteLine(number is int); // True
Console.WriteLine(number is double); // False
Console.WriteLine(number is Customer); // False
Customer customer = new Customer { Name = "John Doe", Age = 30 };
RegularCustomer regularCustomer = new RegularCustomer { Name = "Jane Doe", Age = 25, Discount = 0.1m };
Console.WriteLine(customer is int); // False
Console.WriteLine(customer is Customer); // True
Console.WriteLine(customer is RegularCustomer); // False
Console.WriteLine(regularCustomer is Customer); // True
}
}
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
class RegularCustomer : Customer
{
public decimal Discount { get; set; }
}
The is operator can be used to check the datatype of expression which can be be value type or reference type. In above example, number expression is checked against value type and reference type both. Similarly, reference type customer variable is checked againt value type and reference type both. The as operator is used only for reference type as we will see later.
The is operator returns a Boolean value. It means the result of the is operation can be either True or False. Based on the result, developer can decide whether the conversion will be successful or not. Thereafter inside the if block, the cast operation is done for success.
AS OPERATOR
Second, we consider about as operator. It is a binary operator which takes expression as left operand and a datatype as right operand, very much similar to is operator. It checks if the expression is of the datatype given in the right operand. If true, then expression is evaluated/converted as per the datatype given in the right operand. If false, then it returns null.
The as operator cannot be used to check expression against a value type. The right side operand must be a reference type.
Now, consider the following example:
class Program
{
static void Main(string[] args)
{
int number = 42;
object obj = new object();
obj = number as int; // Compile time error as int is not reference type
obj = number as double; // Compile time error as double is value type
obj = number as Customer; // Compile time error, number cannot be converted to Customer
obj = number as object; // NO Compile time error, number can be boxed inside object
}
}
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
From the above code it is obvious that compiler throws error when value type (int and double) as used againt number expression. The compiler error mesage is as follows:
- The as operator must be used with a reference type or nullable type ('int' is a non-nullable value type)
For the "number as Customer", the compiler error mesage is as follows:
- Cannot convert type 'int' to 'Customer' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
But for the "number as Object", the compiler does not throw any error mesage. The fact is number which is int type is boxed as object type.
Now we modify the above code to allow nullable type:
class Program
{
static void Main(string[] args)
{
int number = 42;
object obj = new object();
obj = number as int?;
Console.WriteLine(obj); // 42
Console.WriteLine(obj.GetType()); // System.Int32
obj = number as double?;
Console.WriteLine(obj); // null
//Console.WriteLine(obj.GetType()); null reference
obj = number as object;
Console.WriteLine(obj); // 42
Console.WriteLine(obj.GetType()); // System.Int32
}
}
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
Note that when right operand is
nullable value type, the compiler does not throw any error mesage. In fact, the expression: number as int? returns value 42 with System.Int32 datatype.