A cast operator explicitly converts a value into a particular data type.
For example, the following code initializes the double variable value1, casts it into the float data type, and then saves the new float value in variable value2.
- double val1 = 20;
- float val2 = (float) val1;
Widening Conversion Converting a reference type to a direct or indirect ancestor class or interface. These sorts of conversions are done implicitly.
For example, if the Employee class is derived from the Person class, you can cast/convert an Employee object into a Person object:
- Employee emp1 = new Employee();
- Person person1 = emp1;
A few point to note about Casting:
- Casting / Converting a reference value to an ancestor class or interface does not actually change the value; it just makes it act as if it were of the new type.
In the previous example, person1 is a variable of type Person, but it references an Employee object. Though person1 can be treated as a Person, it is still an Employee. This kind of casting is widely used when you follow the “Program against Interface” paradigm.
Because person1 is actually an Employee, it can be converted back to an Employee variable. Have a look at the following example:
- Employee employee1 = new Employee();
- Person person1 = emp1;
- Person person2 = new Employee();
// Allowed because person1 is actually an Employee.
- Employee employee2 = (Employee)person1;
- A casting operation is required when converting from Person to Employee. This type conversion is called narrowing conversion.
- Employee employee2 = (Employee)person1;
- Developers have to be careful with narrowing conversions. Consider a scenario when person1 is not actually of employee type (however, in this case it is), the program throws an InvalidCastException exception at run time because this kind of cast operator enables the code to compile.
Example
The following code throws an exception when it tries to cast a true Person object into an Employee:
- Person person1 = new Person();
// Not allowed because person1 is a Person but not an Employee.
- Employee employee3 = (Employee)person1;
Now that we have seen how casting can be done in C# and also the consequences. C# provides two operators “as” and “is” to facilitate safe casting mechanism.
The is Operator
The is operator determines whether an object is compatible with a particular type.
For example, as shown in the following class diagram, the Employee class is derived from Person, and the Manager class is derived from Employee. Developers must pay extra attention when a variable in the program is checked with is operator i.e. variable should be checked as if it is an Employee but not Person. This is important because in either case the result of is operator would be true because an employee is a person too.
Example:
The following code uses the is operator to determine whether the Person variable refers to an Employee and takes a special action:
- if (user is Employee)
- {
-
- }
If the is operator returns true, indicating the variable user refers to an Employee, the code takes whatever action is necessary.
The as Operator The previous code takes special action if the variable user refers to an object that has a type compatible with the Employee class. (In this example, that means user is an Employee or Manager.) The is operator only checks but it does not convert an object of a type to a (right hand side of is operator) checked type. The as operator is used to convert the variable into a more specific class before treating the object as if it were of that class. The following code casts user into an Employee, so it can treat it as an Employee:
- if (usr is Employee)
- {
-
- Employee emp = (Employee) usr;
-
- ...
- }
The as keyword makes this conversion slightly easier. The statement object as Class returns the object converted into the indicated class if the object is compatible with the class, the statement returns null.
The following code shows the previous example rewritten to use the as operator:
- Employee emp = usr as Employee;
- if (emp != null)
- {
-
- }
NOTE
Whether you use the earlier version that uses is, or this version that uses as, is largely a matter of personal preference.