Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Casting options in C#

    What is the best way to cast from one type to another in C#?  This question came up at work last week while I was looking through some older code.  The code in question was using the C style casting syntax.  I have started to use the "as" style cast more often and rewrote it.  Then I decided to do some research into the differences between the two styles to find out if one really is better than the other.

    The most obvious difference is that a C style case will throw and exception if the cast fails and the "as" style cast will simply return null.  So first you need to take into consideration what these differences will have on your code.  Will you need to wrap every cast in try/catch blocks?  Not if you use the "as" style, but you will need to check for null.  What about performance?

    I read a dozen or so blog posts on the subject and they seemed to be pretty evenly divided with half insisting that one style was obviously superior and the other half convinced their chosen style was better.  That didn't really help so I decided to do some testing on my own.

    I've attached a small test project for reference, it will allow you to select the number of casts to perform and the style and return the total time and average for each cast.  First let's see what the difference looks like in IL (o is of type object in these examples).

((Person) o).Name becomes: IL_0036: castclass CastTest.Person Person p = o as Person; becomes: IL_0036: isinst CastTest.Person

   So there is a difference at the IL level but is one a better performer?  I wrote three different test projects, the last of which you will find attached to this post.  Why did I write three?  Because with each test I was convinced that my results must be skewed because I was not seeing the  performance difference I expected.  I ran test casting 100,000, 1,000,000, 10,000,000 and 100,000,000 objects many times in difference orders, restarting the application between tests, not restarting between tests, clicking the button with my left hand, clicking with my right hand, every combination I could think of.

    What did I discover?  It was pretty anticlimactic.  In my opinion the difference was completely negligible.  That is, negligible if you aren't throwing exceptions when casting with the C style cast.  The most stable set of test results I could get were casting 1,000,000 objects.  In this case, either style averaged 10.1 seconds total and averaged 0.0101 milliseconds.  We're talking about a difference of 0.00005 milliseconds per cast.  I can't really get worked up over that.  Of course, if you throw exceptions for each C style cast in that test, it's over 10 times slower.  That's something to consider!

   So will I pick one over the other?  The answer is an emphatic "meh".  In code I will probably use the "as" style.  When doing things in markup related to databinding it's extremely useful to be able to use the C style cast and I will continue to do so.


Posted 10-07-2007 2:27 PM by anortham
Filed under: , ,
Attachment: CastTest.zip

[Advertisement]

Comments

Style » Casting options in C# wrote Style » Casting options in C#
on 10-07-2007 5:56 PM

Pingback from  Style » Casting options in C#

Weex wrote re: Casting options in C#
on 10-07-2007 8:50 PM

Exceptions are a good thing. Why do you fear them? Why do you think you should enclose every casting in a try/catch block? More importantly, what you can really do about it, if it actually throws an exception?

Obviously, you can fix it, so it won't happen again.

Generally, you have only several places in your application where you care about exceptions, i.e. you can something meaningful about it (e.g. log).

So, exceptions when casting are GOOD. Using an "as" like you describe in your post, i.e. as a matter of preference, style if you want, you will only mask/hide problems. And those need to be solved, not hidden (NullReferenceException anyone?).

And no, I'm not saying that "as" doesn't have a use or it's bad. I'm saying that you are misusing it. Measuring performance of casting operators isn't something you should really be interested in, if only for fun :)

anortham wrote re: Casting options in C#
on 10-08-2007 9:34 AM

Weex:

I didn't say I feared exceptions anywhere in the post.  If you read it again, you will see that I ask the question if *YOU* will need to wrap your casts in try/catch blocks.  If you do depends on your coding style and the context of the code.    

RE: NullReferenceExceptions, if you look at the code included you will see that after casting with "as" the first thing you do is check for null.

Weex wrote re: Casting options in C#
on 10-08-2007 11:34 AM

Sorry if it looked like an attack, no offense. I may have misread you.

Still, i don't agree with you (even after re-reading the post). You ask "What is the best way to cast from one type to another in C#?". That is not the question you want to ask. You make a valuable addition in you comment about the context. So, the question should be "what is the best option in my context?". Then it becomes clear that each casting operator has it's own meaning, it's own semantics. To paraphrase you question, "what is the best way to eat: with fork or spoon?"

Long story short, you choice of casting operator should not be influenced by your coding style or personal preferences (as it looks like from your post, at least for me), only by your context. And you really want to use C-style operator most of the time. Using "as" all over the place leads to error masking\hiding.

P.S. Looking at the source code included I don't see any null checks :)

anortham wrote re: Casting options in C#
on 10-08-2007 11:57 AM

Weex:

The question of which way is best is what prompted me to write this post.  However, my conclusion ("meh") is that I don't really see one as superior to the other and I plan on using each in the proper context.  I think we agree on this.

There are two methods for the "as" style of cast in the source code, one has a null check ( if(p != null)) and one doesn't.  I didn't go into that in the post but I wanted to include it in the code to see how much of a factor that would be in the performance.  But as I said, there really wasn't any significant difference in any of the methods (unless you start throwing exceptions).

There are certainly cases where I would want to throw an exception if the cast failed.  The specific code that caused this question to come up in the first place was inside the ItemDataBound method of a DataList.  In that instance I knew for a fact that the object would always successfully cast.

MS MVP wrote re: Casting options in C#
on 10-19-2007 9:44 AM

IMHO, using the c style cast is more thorough than the "as" style.  The c style cast not only allows you to determine if your object is null but if it is null due to a cast exception.  The later can never be determined using the "as" method.  As a developer I want to know when an object is really null versus when an object has been set to null because of a casting problem.  Furthermore, I never make assumptions that something in my code will always be successful.  I tend to code more similar to java developers.  If something can throw an exception I like to catch the exception or continue throwing it.

Alan Northam wrote Databinding performance tip in ASP.NET
on 10-22-2007 2:42 PM

In my last post I mentioned the use of C style casting when databinding in ASP.NET. That got me thinking

Christopher Bennage wrote re: Casting options in C#
on 10-22-2007 8:38 PM

@Weex: "what is the best way to eat: with fork or spoon?"  I like that.

I'm not saying anything new, really but my motivation regarding the choice of casting operators is driven by maintainability.  Which operator, given the context, makes the intention more explicit?  

lee wrote re: Casting options in C#
on 09-07-2008 3:45 AM

There is also another difference that you failed to mention: C style casting works well for reference types AND for value types - while the "as" style ONLY works for reference types

this difference can be crucial when you try to write generic code

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)