We all know and have experienced the importance we have for castings in C#. Its just essential if you want to build any system that takes inputs, process and give output. What a basic computer does is the same functionality right? so logically we need casting
EVERYWHERE in computing. Even you can argue, “I am a C# programmer, I write a console application that takes two integers, calculate their sum of it and print the output, so where I have to cast here?” my answer is “CLR does this”.
In simple and understandable words, “casts are basically explicit conversion”. In internal conversions we can pretty much ensure on three things
- No special syntax required
- They are type safe
- No data-loss
Normally we can take conversions from smaller to larger integral types and conversions from derived classes to base classes as good examples for this type of internal conversions. Explicit conversions, require a cast operator. We have to explicitly say the
compiler to forcefully convert the type. So there might be a very possible data-loss.
Honestly (Un)Boxing is a subset of casting. Boxing means CLI consider a value type as reference type (that involves copying the contents of that particular value type which is on stack to the heap and returning a
reference to the particular object). This lets a value type to be passed wherever a compatible reference type is expected and also this allows virtual method calls and some other features of reference types to be processed on the value type. Unboxing
is the reverse of this boxing operation (getting back a value type out of a boxed object). Casting is taking a type (say, System.Int32) and consider it as another type (say, System.Double). When you box something in C#, you are casting it to another type.
The difference is that it allocates additional memory as a new reference type is created.
is are used in C# to safely cast things. Since C# objects are polymorphic its possible that a base class type variable can hold a derived type so to access the derived type’s method, it is necessary to cast the
value back to the derived type. However this has a risk of
InvalidCastException. This is where
is comes to the play.
is is used to check the compatibility of two objects with a given type and returns
as can used only with reference type and will return
null if casting fails. basically
Think of the below code piece,
Simply you can argue, this is a confusing and a useless way since we are using
keyword we are not sure about if
BAT is a type of
MAMMAL and yet we are invoking a method. And even worse, this code piece can make a meaningful
InvalidCastException to a
NullReferenceException we all hate it. But why in some places they have mentioned this kind of a code piece? this is where code readability comes to mind. We know if we are using
as, we are sure about this object can be converted to that type but if it can’t we are happy to accept a
null. However as I said before
as can only be used with reference types, by using this style of coding, we can tell code reader that the code involves only reference or unboxing conversions, and furthermore, that BAT is not null.
is does almost the same but by stating
we can say it can be a derived type or from interface. So again using
in necessary places ensures code readability and sometimes. Still to use
typeof properly we have to use
GetType() can be used closely to work with
typeof there is a slight different.
typeof is used when you want to get the Type instance representing a specific type.
GetType() gives the runtime type of the object on which it is called, which may be different from the declared type. The below example make a clarification on it.
Always remember, GetType actually queries a specific assembly (at runtime) for a type that might be defined within the assembly (Similar to new Object().GetType()). typeof on the other hand is determined at compile time.
Using GetType() in some instances might lead us to a null related exception, since this function has been defined something like below
So when we call this, this will only check from the calling assembly and some few other system assemblies (probably System and mscorlib). It does not check every assembly. So the string parameter inside GetType() sometimes needed to be a fully-qualified assembly
name. Thus in performance, typeof() takes little time than GetType() to get executed. Consider the example below
This will return the following output
I hope this will make more sense when you try to understand the above scenario.
This artcle, I originally wrote for Technet. http://social.technet.microsoft.com/wiki/contents/articles/32293.c-casting-and-type-checking.aspx