Home > Sample chapters

Understanding Values and References in Microsoft Visual C#

Casting data safely

By using a cast, you can specify that, in your opinion, the data referenced by an object has a specific type and that it is safe to reference the object by using that type. The key phrase here is “in your opinion.” The C# compiler will not check that this is the case, but the runtime will. If the type of object in memory does not match the cast, the runtime will throw an InvalidCastException, as described in the preceding section. You should be prepared to catch this exception and handle it appropriately if it occurs.

However, catching an exception and attempting to recover in the event that the type of an object is not what you expected it to be is a rather cumbersome approach. C# provides two more very useful operators that can help you perform casting in a much more elegant manner: the is and as operators.

The is operator

You can use the is operator to verify that the type of an object is what you expect it to be, like this:

WrappedInt wi = new WrappedInt();
...
object o = wi;
if (o is WrappedInt)
{
    WrappedInt temp = (WrappedInt)o; // This is safe; o is a WrappedInt
    ...
}

The is operator takes two operands: a reference to an object on the left, and the name of a type on the right. If the type of the object referenced on the heap has the specified type, is evaluates to true; otherwise, is evaluates to false. The preceding code attempts to cast the reference to the object variable o only if it knows that the cast will succeed.

The as operator

The as operator fulfills a similar role to is but in a slightly truncated manner. You use the as operator like this:

WrappedInt wi = new WrappedInt();
...
object o = wi;
WrappedInt temp = o as WrappedInt;
if (temp != null)
{
    ...  // Cast was successful
}

Like the is operator, the as operator takes an object and a type as its operands. The runtime attempts to cast the object to the specified type. If the cast is successful, the result is returned and, in this example, is assigned to the WrappedInt variable temp. If the cast is unsuccessful, the as operator evaluates to the null value and assigns that to temp instead.

There is a little more to the is and as operators than is described here, and Chapter 12 discusses them in greater detail.