The 3 cast operators in C#
There are three cast operators in C#. The first is the traditional cast operator that uses parentheses, the second is the "is" operator, and the third is the "as" operator.
Normal Casts
This operator uses the same syntax as the original C cast operator. The key thing is that it always returns an instance of the type you are requesting. If it can't do the cast, then it throws an exception. The majority of the time this is the desired behavior, because you want an exception earlier in your code rather than later.
object o = "hi"; string s = (string)o; // works double d = (double)o; // throws an exception since it can't return a double
The "is" operator
This operator doesn't actually return the result of the cast. It simply returns whether the cast would have succeeded. This is handy when you want to ask if an object is an instance of a type, but you don't actually need an instance of the type. This operator is pretty useful, but it turns out that most of the time you really want to use the "as" operator, however, there are times when you really do want the is operator.
if (o is string) lblType.Text = "o is a string"; if (o is double) lblType.Text = "o is a double";
Some people might disagree that the "is" operator is a cast. They might say that it is a runtime type check or something like that, but type references in .net have the same value before and after a cast. This means that the normal cast simply does a runtime type check and if the result if false, then it throws an exception.
The "as" operator
The "as" operator returns an instance of the type request, but if it cannot do the cast, it will return null. This operator is handy for fixing the most common pattern for using the "is" operator. Since the "is" operator is a cast in disguise, when people use the "is" operator they usually end up doing two casts, and the "as" operator allows you to avoid the double cast.
if (o is string) {
string s = (string)o; // wrong because we are doing 2 casts
lblO.Text = s;
}
string s = o as string;
if (s != null) lblO.Text = s;In C# v2, the as operator becomes even nicer with the null coalescing, because you can easily replace a non-matching cast with a desirable default.
lbl0.Text = o as string ?? "No value given";
Common Mistakes
When I first learned about the "as" operator, I used it a bunch, and I ended up with code like this:
Converter c = x as Converter; c.DoConversion();
The problem with the above code is that if the cast fails, then the second line throws an exception. If that cast fails, then you really want a cast excpetion and not a null exception, since the cast tells you a lot more information about the problem.
The other bad thing I did was before I learned about the "as" operator. I did this a lot:
if (x is Converter) ((Converter)x).DoConversion();
This doesn't throw an exception, but it does do two casts. Casts are not as expensive in .net as they are in many other languages, but they are still non-trivial, so you want to avoid unneeded casts.
Please
log in or register to comment.