C# is a type-safe language. This means that a value of one type can only be assigned to a variable of a compatible type. As a result, developers often need to check the type of an expression or convert it from one type to another.
C# provides several mechanisms for this purpose:
- The is operator checks whether an expression is compatible with a specified type.
- The as operator attempts a safe conversion and returns null if the conversion fails.
- The cast operator ((Type)) performs an explicit conversion and throws an exception if the conversion is invalid.
Understanding these operators is essential for every C# developer because they are frequently used in day-to-day programming.
The is Operator
The is operator is a binary operator. It takes:
- An expression as the left operand.
- A type as the right operand.
It checks whether the runtime type of the expression is compatible with the specified type and returns a Boolean value (true or false).
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; } = string.Empty;
public int Age { get; set; }
}
class RegularCustomer : Customer
{
public decimal Discount { get; set; }
}
The is operator works with both value types and reference types. The result of the operation is always either true or false.
A common use of the is operator is to determine whether a cast can be performed safely.
For example:
if (customer is RegularCustomer)
{
RegularCustomer rc = (RegularCustomer)customer;
}
The as Operator
The as operator is also a binary operator. Like the is operator, it takes:
- An expression as the left operand.
- A type as the right operand.
However, instead of returning true or false, it attempts a conversion.
If the conversion succeeds, the converted value is returned. If the conversion fails, null is returned.
Unlike the cast operator, the as operator never throws an InvalidCastException.
Consider the following example:
object obj = "Hello World";
string? text = obj as string;
Console.WriteLine(text); // Hello World
Customer? customer = obj as Customer;
Console.WriteLine(customer == null); // True
In the first conversion, obj contains a string, so the conversion succeeds.
In the second conversion, obj does not contain a Customer, so the conversion fails and null is returned.
Restrictions of the as Operator
The as operator cannot perform arbitrary conversions.
It works only when a valid conversion exists, such as:
- Reference conversions
- Nullable conversions
- Boxing conversions
- Unboxing conversions
For example:
int number = 42;
object? obj = number as object;
Console.WriteLine(obj); // 42
Console.WriteLine(obj.GetType()); // System.Int32
The conversion succeeds because an int can be boxed into an object.
Similarly:
int number = 42;
int? nullableNumber = number as int?;
Console.WriteLine(nullableNumber); // 42
The conversion succeeds because there is a valid conversion from int to int?.
However, the following code does not compile:
int number = 42;
Customer? customer = number as Customer;
Compiler error:
Cannot convert type 'int' to 'Customer' via a reference conversion,
boxing conversion, unboxing conversion, wrapping conversion,
or null type conversion
Likewise, the following code does not compile:
int number = 42;
double? value = number as double?;
Although an ordinary numeric conversion exists from int to double, the as operator does not perform numeric conversions.
The Cast Operator
The cast operator uses the following syntax:
(Type)expression
It attempts to convert an expression to the specified type.
Unlike the as operator:
- A successful cast returns the converted value.
- An unsuccessful cast throws an exception.
Consider the following example:
object obj = "Hello";
string text = (string)obj;
Console.WriteLine(text);
The cast succeeds because obj actually refers to a string object.
Now consider:
object obj = "Hello";
Customer customer = (Customer)obj;
This code compiles successfully because the compiler sees that a cast might be possible.
However, at runtime it throws:
InvalidCastException
because the object actually contains a string rather than a Customer.|
Feature |
is |
as |
Cast ((Type)) |
|
Purpose |
Check type compatibility |
Attempt safe conversion |
Perform explicit conversion |
|
Return type |
bool |
Converted value or null |
Converted value |
|
Throws exception on failure |
No |
No |
Yes (InvalidCastException) |
|
Can perform numeric conversions |
No |
No |
Yes (when supported) |
|
Useful for safe type testing |
Yes |
Yes |
No |
When Should You Use Each?
Use is when you only want to know whether an object is compatible with a particular type.
if (obj is Customer)
{
// Safe to proceed
}
Use as when working with reference types or nullable types and you want a safe conversion that returns null instead of throwing an exception.
Customer? customer = obj as Customer;
if (customer != null)
{
// Use customer
}
Use a cast when you are certain the conversion is valid or when you want an exception to be thrown if it is not.
Customer customer = (Customer)obj;
Summary
- The is operator checks whether an expression is compatible with a specified type and returns true or false.
- The as operator attempts a safe conversion and returns null if the conversion fails.
- The cast operator performs an explicit conversion and throws an exception if the conversion is invalid.
- The as operator supports reference conversions, nullable conversions, boxing conversions, and unboxing conversions, but it does not perform numeric conversions.
- Choosing the appropriate operator improves code safety, readability, and reliability.
No comments:
Post a Comment