Casting and Converting types in .Net (using C#) - Part II
C# is a type-safe and strongly typed language. If your method expects int and you are passing string, will not be compiled. Here the casting/converting plays a role. .Net allows you to convert between types.
This article is second of a two-part series. The first part focuses on converting, the current is on casting. The following are the links for both parts.
Part I : Converting
Part II : Casting
Casting:
For primitive types we convert and for complex types we use type casting. There are two types of type casting i.e. implicit and explicit. Implicit casting is taken care by CLR. Explicit casting, developer needs to handle.
Implicit:
Implicit conversions are handled by CLR. For this developer need not give any special syntax to cast.
In . net, all child classes can be type cast to its base class.
For eg.
class Person
{
public string Name { get; set; }
}
class Employee : Person
{
}
In the above mentioned classes, Person is base class and Employee extends (inherits) Person. So, every employee is a person. Hence no type cast required.
Person per = new Employee(); //Valid.1
Another example
Let’s assume we have a method save data taking person as parameter. Now we can pass all child classes of this parent class as parameter to this method.
void SaveData(Person p)2
{
}
Employee emp = new Employee();
emp.Name = "Isabella";
SaveData(emp); //Valid.
Explicit:
Explicit type casting needs developer effort. It requires syntax. Explicit type casting is done at runtime. If unable to type cast or incorrect types are being type cast, then an exception(InvalidCastException) will be thrown.
Most of my programming life, I spent on asp.net. If you are a asp.net developer, I bet you would have used FindControl method. This FindControl method returns ‘object’ but you would be looking for TextBox, DDL or any other server control. So what are you going to do?
TextBox txtName = (TextBox)e.Row.FindControl("txtName");3
txtName.Text = "ASP.NET";
So what if txtName not available and FindControl returns null. Yes. Exception is thrown. Whenever you write a program, you need to estimate what are the places which are exception prone, then handle it in a way to suppress exception. In this scenario, if we type cast FindControl object to textbox with “as” keyword then the result would be different.
TextBox txtName = e.Row.FindControl("txtName") as TextBox;
txtName.Text = "ASP.NET";
What's happening now? “as” type cast, tries to cast it. If its unable to cast then it returns null. In our example, FindControl doesnot find anything and returns null. Type casting the result to textbox returns null. So text name is null. Did we get any exception? No. Then what next? Once you got a type, you would be accessing it (that’s why we do type cast.Right?). Accessing something from null, now exception (Null reference) is thrown. We suppressed one and created a new exception. Don’t worry this would be handled easily, by checking for null.
TextBox txtName = e.Row.FindControl("txtName") as TextBox;4
if (txtName != null)
{
txtName.Text = "ASP.NET";
}
Let’s try with dropdownlist and typecast it to text box.
TextBox txtName = e.Row.FindControl("ddlCountry") as TextBox;
This is also not permitted. Hence txtName is null only. We are good if we have null check after this statement.
Now do you want to try with person object? Play around it.
I'lI modify SaveData method to accept any object as input.
void SaveData(object input)
{
//Valid. Exception prone.
Person p1 = (Person)input;
//Valid and safe. Be sure to check for null.
Person p2 = input as Person;
}
Too smart :) : Now, I know that “as” is good. And always use it. So, I started thinking why should I convert at all? I can go for ‘as’ and typecast it to my wish.
//Invalid. 'as' must be used with reference type.
int number = "20" as int; 5
//Invalid. int can not be null.
if (number != null)
{
}
Only reference types can use “as”.

- Every child class is a base class whereas the converse is false. Employee is a person but person may not be employee, he might be a student. So you cannot create instance of parent class into child variable. And you cannot convert a parent to child.
Employee emp = new Person(); //Invalid
Employee emp = (Employee)per; //Invaid - per is person object - Whenever I create a method I will check what are the params. If a param is an object of complex type then I check if any parent exists, then I will change the param to parent type or its interface type instead of that concrete class. This makes my method reusable and can be used for other child classes too.
- If we work on any data control and to handle a specific child control in that data control, we use FindControl of particular databound. The code e.Row.FindControl() represents RowDataBound event of GridView. In this event we can track every row of grid. This concept is widely used for handling controls behavior.
- We have “is” operator to check for its type. "is" operator checks if the provided object is X type or not and retruns the boolean. If it returns true then we can type cast. This way we need not check for null because it ”is” valid. But performance wise, it’s a bad practice to use “is” and type cast it.
if(e.Row.FindControl("txtName") is TextBox)
{
// Now it doesn't matter how you cast.
TextBox txtName1 = (TextBox)e.Row.FindControl("txtName");
TextBox txtName2 = e.Row.FindControl("txtName") as TextBox;
}
- All value types are non-nullable. To make it null, we have to wrap it in Nullable struct. Syntax is T? or Nullable<T>. Now T and nullable T are different types i.e., T != Nullable<T>.