Well – “as” is faster to type than a “real” cast using two brackets and has the same result. Really?
C# provides several ways to cast one type to another one. The two used in most cases are the “
([Targettype]) [Variable]” and the “
[Variable] as [Targettype]” notations. Many developers see them as equivalents, some even prefer “as” because it does not throw an exception when the cast fails.
Let’s say we have a variable called obj of type Object and we want to cast it to an IFoo so we can call IFoo.Bar:
object obj; //... (obj as IFoo).Bar();
What does it do?
In line we are using as to cast obj to type IFoo as we can not call this method directly on an Object.
What does it actually do?
Well – it works great…
…as long as obj can be converted to IFoo. If not, however, there will occur a NullReferenceException even if obj is not null. You can try this by replacing the comment in line two with the following code:
obj = 53;
However, the real problem is not a null reference, but a failed cast. What we would expect is a InvalidCastException. So debugging is complicated considerably as we get a confusing error message. On the other hand, as could not avoid an exception what we might have thought when deciding to use it.
The MSDN (C# Reference: as) says:
The as operator is similar to a cast operation; however, if the conversion is not possible, as returns null instead of raising an exception.
We can say: We have no problem until someone reports a bug where the message lets us think we have a null reference somewhere.
The problem is that Bar is called regardless whether the cast successes or not. If it doesn’t
(obj as IFoo) returns null and we call Bar on a null-reference.
How to solve?
Avoid casting. Use object-oriented techniques instead.
If that’s not possible, the solution depends on what you intended to do:
Do you think the cast will always succeed (if your program is written correctly)? Then use a “traditional”, explicit cast. It will provide you with more precise information than a cast using as.
Or was your idea only to call Bar if obj really is an IFoo? Then use the following snippet:
IFoo foo = obj as IFoo; if (foo != null) foo.Bar();
Conclusion / Best Practice
Only use as in combination with an if-Statement verifying the result of the cast is not null.
Otherwise, use explicit casts.