Sunday, August 21, 2011

C# Type Casting: Prefix Vs. ‘as’ casting

Type casting in C#.
Prefix Vs. ‘as’ casting
Little bit over Boxing and unboxing.
You will find lot of article written on this subject on net. I have referred Emilio Guijarro ‘s ‘Type casting impact over execution performance in C#and Paul Houle’sPrefix-casting versus as-casting in C#
We are going to see
clip_image001[28] Prefix cast usage,
clip_image001[29] ‘as’ keyword usage
clip_image001[30] and Difference between both
clip_image001[31] Performance impact
May be following article is not written in this order though. Those who know difference between prefix cast and ‘as’ may only need to have a cursory glance over this write up.
clip_image001[32] Prefix type casting:
For Class A, B and C
imageimageimage


Usage:
image
For following scenario,
image
clip_image001[33] ‘as’ Keyword :
As mentioned in msdn ,
Implies,
image
Because,
image
In this case the next statement will fail and throw ‘NullReferenceException’ which does not seem to be good thing, because where
You are expecting ‘InvalidCastException’ you will get ‘NullReferenceException’.
‘as’ keyword does not work with non nullable types where prefix casting works for it, i.e. ‘as’ won’t work with int, short, bool etc..

Difference between both:
image











Disassembly :
image


MSIL :
image


Disassembly :
image



MSIL :
image



As mentioned by Emilio Guijarro, The compiler emits a "Castclass" opcode, which converts the reference to the type specified between the parenthesis if possible (if not, an ‘InvalidCastException’ exception is thrown). The ‘as‘ keyword is translated as an "IsInst" opcode, which works much faster, because it only checks the reference type but doesn't perform any sort of cast (nor throws any exception). This can be observed by looking at disassembly code.
clip_image001[34] Following is the graph shown by Emilio for type casting of several value types:
image

clip_image001[35] That concludes ‘as’ is faster than prefix cast.

Eric Lippert has mentioned in one of his blog ,
The use cases of the two operators (‘as’ and prefix cast) are superficially similar, but semantically quite different. A cast communicates to the reader "I am certain that this conversion is legal and I am willing to take a runtime exception if I'm wrong". The "as" operator communicates "I don't know if this conversion is legal or not; we're going to give it a try and see how it goes".

[NOTE: just to mention out of this context, important to remember that any value type(T) if Boxed can be unboxed to type T only]
So, you must have figured out the difference between both by now. We will see when one should use which type of casts.
Using ‘as‘
image
clip_image001[36] When you are not sure which type of object is being downcast from Object of type ‘A’ its better to use ‘as’ keyword
clip_image001[37] Or , When type casting is to be done inside a loop, ‘as’ must be preferred, as we have seen it is faster than prefix casting.
clip_image001[38] Where you do not wish to throw ‘InvalidCastException’ exception, on contrary want to handle in the way similar to shown in above example.
clip_image001[39] Correct error handling often requires more contorted logic than using an exception — and once you added test logic, you’ve lost the speed advantage of as-casting. For complex object hierarchy this validation logic may become really complex and difficult to maintain.
clip_image001[40] Now, to all non C# programmers would argue about why would one need ‘as’ operator anywhere, this above is the reason. J

Using ()prefix cast:
image
· You are certain that object a1 will be of type B always. Or you expect it to be of type B only else you want to throw exception.
· In this case using ‘as’ and writing code for null check and other control logic makes no sense as by writing that logic speed benefit of ‘as’ operator is already compromised.
· Use in generic methods like cool at following pseudo code
Purpose is to get property of object ‘obj’ of name ‘ColName’ , you expect it to be of type ‘R’
And get OUTPUT only if it not blank or null. (just a sample don’t bother about logic please J)
In this case you may have type ‘R’ as int, bool value types of any complex type also, so using ‘as’ is out of question.
The Big Question, which one should usually be preferred image
  • Well I googled and doodled... J So here is the truth.
  • Answer to this question is trivial, yeah! But following are point you may want to remember.
  • · Use ‘as’ operator in loops or in recursive functions if performance is an issue and you exactly know what type will be converted to what type and you are ascertain t will not cause ‘NullReferenceException’ or you are fine if exception is thrown from that peace of code.
  • · Use ‘as’ where performance is of high importance and you don’t need to deal with value types or non nullable types.
  • · Else only use () prefix cast.

0 comments:

Post a Comment