Prefix-casting versus as-casting in C#
Introduction
This is a story of two types: GenericType and SpecificType, where GenericType is a superclass of SpecificType. There are two types of explicit cast in C#:
The Prefix cast:
[01] GenericType g=...; [02] SpecificType t=(SpecificType) g;
The as cast:
[03] GenericType g=...; [04] SpecificType t=g as SpecificType;
Most programmers have a habit of using one or the other — this isn’t usually a conscious decision, but more of a function of which form a programmer saw first. I, for instance, programmed in Java before I learned C#, so I was already in the prefix cast habit. People with a Visual Basic background often do the opposite. There are real differences between the two casting operators which can make a difference in the reliability and performance of your application.
Prefix casting: Reliable Casting
The major difference between prefix- and as-casting is what happens when the cast fails. Imagine, for instance, that g is really an instance of AnotherSpecificType, which is not a subclass of SpecificType. In this case, the prefix-cast throws an exception at line [2] — however, the as-cast returns null when the cast fails, letting the execution of the program barrel on.
It’s easier to implement correct error handling in programs that use prefix-casting, and programs that use prefix-casting are easier to debug. Prefix-casting causes an exception to be thrown at the moment of the cast, where the problem is obvious. As-casting, on the other hand, can cause an exception to be thrown at the moment where the SpecificType t is referenced. The used of the SpecificType can be far away in the program: it can be in another method, or another class — it could even happen hours after the cast is performed. Be it in development or production, bugs caused by corrupted data structures can be maddeningly difficult to find and correct.
As-casting: Fast Casting
If it’s harder to write correct programs with as-casting, why would anybody use it? For one thing, as-casting is faster than prefix casting by quite a lot. Benchmarks show that as-casting is about five times faster than prefix casting. That said, the performance of casting is only going to matter in the innermost of loops of most programs. The fastest kind of casting is no casting at all: it’s best to use generics to eliminate the need for casting when possible and to move casting outside loops. (Generics also improve the reliability of your code because they help C#’s static type checking catch mistakes.)
There are some cases where as-casting could be convenient, for instance, when you expect the cast to fail sometimes. Often I like to ‘tag’ classes with interfaces that specify certain behaviors. For example,
[05] public Interface IBoppable {
[06] void Bop();
[07] }
Now i might want to loop through a bunch of Thing objects, and bop all the ones that implement IBoppable: it’s reasonable to use as-casting here:
[08] List<Thing> list=...
[09] foreach(Thing thing in list) {
[10] List boppable=thing as IBoppable;
[11] if (boppable !=null) {
[12] boppable.Bop()
[13] }
[14] }
It’s OK to use as-casting if you’re going to check to see if the value is null immediately after the cast. The above code is correct, but has the bad smell that the boppable variable continues to exist in the block after the cast… It’s still there for a later maintainer to use erroneously. In cases like this, code can be made clearer with the is operator:
[15] List<Thing> list=...
[16] foreach(Thing thing in list) {
[17] if(thing is IBoppable) {
[18] ((IBoppable) boppable).Bop()
[19] }
[20] }
(Speed freaks can use as-cast on line 18, as we know it’s not going to fail.)
The pattern of testing for null after an as-cast has a few problems. (i) It doesn’t distinguish between the case of the original object being null from the case of the original object being the wrong type and (ii) 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.
Conclusion
C# offers two casting operators: the prefix-cast and the as-cast. Although the two operators compile to different op-codes in the CLR, the practical difference between them is in how they handle failed casts. Prefix-cast throws an exception on cast failure, while as-cast returns null. It’s easier to implement correct error handling when you use prefix cast, because it doesn’t require manual checks for null values that can cause problems in distant parts of your program. Prefix-cast should be the default cast operator on your fingertips, that you use for everyday situations — reserve as-cast for special cases where performance matters. (For best performance, however, eliminate the cast entirely.)
Paul Houle on June 13th 2008 in Dot Net
![[Generation Five]](/q/wp-content/themes/mach-go/images/GenerationFive.png)
![[Reliable And Maintainable Software For The Next Generation]](/q/wp-content/themes/mach-go/images/ReliableAndMaintainableSoftwareForTheNextGeneration.png)

Reflective Perspective - Chris Alcock » The Morning Brew #116 responded on 16 Jun 2008 at 11:49 pm #
[...] Prefix-casting versus as-casting in C# - An interesting post on the differences between the two ways of casting, and talks a little about cast performance. [...]
Michael james responded on 17 Jun 2008 at 12:24 am #
Great post, i learnt something new today. I always use type cast but have colleagues that use as. Knowing the difference will be a great help
Will responded on 17 Jun 2008 at 8:09 am #
I disagree. I’d say the rule of thumb is:
If you cannot continue if the cast fails, then use the prefix style cast, which will result in an exception.
If you can continue if the cast fails, then use a combination of “if object is type … ” and “as” casts.
You should NEVER do this:
MyType t;
try { t = (MyType)foo; }
catch { // do something here if cast fails and return }
// do something here if cast succeeds and return
That’s a situation where “is” and “as” operators are useful. An example would be checking addins to see if they implement IDisposable. You won’t know this at compile time, so you’ll have to make some type of check.
I’ve found that the majority of time I can handle invalid casts more often than not, so the majority of time I’m using “is” and “as”.
Janko responded on 17 Jun 2008 at 12:22 pm #
Very good article!
cristian responded on 18 Jun 2008 at 12:14 pm #
Hi there, nice post. I think you should mention or write a post about about explicit type conversion. It’s an important distinction of “prefix-casting”.
Sebastian responded on 18 Jun 2008 at 12:53 pm #
I don’t think articles about performance in .Net 1.1 should be used as a reference in 2008. Just read the article’s comments or try it yourself before making such conclusions.
.
IF you want performance then do the _exact opposite_ of your “IBobbable” example. The first snippet (as) will use isinst (and a branch instruction) whereas the is-cast snippet will use isinst and castclass. A quick test shows a performance gain of about 12%, whew! This as-null pattern is the only place I use that operator. And now guess which use of “as” can be found in the “as keyword [C#]” SDK article
Tim C responded on 18 Jun 2008 at 1:20 pm #
“as” is faster? Sample code to back that up? In my testing it was for all intents and purposes EXACTLY the same.
Zack Owens responded on 18 Jun 2008 at 3:10 pm #
I’m not quite sure there is a situation that would require one type of cast over the other when you are dealing with classes or interfaces. Both are interchangeable syntactically and logically.
But also keep in mind that the as operator will only work for classes and interfaces. You must use the prefix cast when working with an enum or struct. The is operator, however, will work with enums and structs.
Maarten Oosterhoff responded on 19 Jun 2008 at 12:15 am #
Another difference is that value types cannot be cast using the ‘as’ keyword, you must us prefix-casting for value-types.
I usually use the is/as keyword, I find that works best for me to understand the code.
Nice article though!
Petar Petrov responded on 19 Jun 2008 at 1:46 am #
I totally agree with Will.
I always use “as” operator over “is”+”as”. However there is situations where I want to force the type so I use the prefix cast.
Anu Viswan responded on 25 Aug 2008 at 10:12 am #
Hi
I would disagree with you on the latter part in which you mentioned “as” casting is faster.
Can you provide some code sample to support your claim ??
Thanks
Anu
Paul Houle responded on 25 Aug 2008 at 3:53 pm #
@Anu,
according to reports I’ve seen, the performance of as- and prefix casts have largely converged as of .net 3.5. It would be interesting to run tests on mono as well.
At this point, I think people should use whatever convention they think is better from a sofware engineering standpoint. In most cases, I think it’s better to get an exception early rather than face a null pointer deference later. On the other hand, there are definitely cases where the as-cast semantics are exactly what you want.
Anu Viswan responded on 26 Aug 2008 at 10:38 am #
Thanks Paul for your kind reply. I understand the speed difference is trivial and doesnt really makes too much impact in real life application. Only thing that would matter is how each handle exception, which again you were spot on that its better to catch an exception earlier than face null later.
I was just curious about the differnce. After i read your article, i tried out my little study on differnce and it seems like prefix casting uses “castclass” function in the IL code generated while “as” casting would use isinst.
Reading about these IL commands, made me wunder again.
Did you happen to check out the differnce in IL ?