Recipe3.14.Casting with the as Operator


Recipe 3.14. Casting with the as Operator

Problem

Ordinarily, when you attempt a casting operation, the .NET Common Language Runtime generates an InvalidCastException if the cast fails. Often, though, you cannot guarantee in advance that a cast will succeed, but you also do not want the overhead of handling an InvalidCastException.

Solution

Use the as operator. The as operator attempts the casting operation, but if the cast fails, the expression returns a null instead of throwing an exception. If the cast succeeds, the expression returns the converted value. The code that follows shows how the as operator is used.

 public static void ConvertObj(Specific specificObj) {     Base baseObj = specificObj as Base;     if (baseObj == null)     {         // Cast failed.     }     else     {         // Cast was successful.     } } 

where the Specific type derives from the Base type:

 public class Base {} public class Specific : Base {} 

In this code fragment, the as operator is used to attempt to cast the SpecificObj to the type Base. The next lines contain an if-else statement that tests the variable baseObj to determine whether it is equal to null. If it is equal to null, you should prevent any use of this variable, since it might cause a NullReferenceException to be thrown.

Discussion

The as operator has the following syntax:

 expression  as  type  

The expression and type are defined as follows:


expression

A reference type


type

The type to which to cast the object defined by expression

This operation returns expression cast to the type defined by type if the cast succeeds. If the cast fails, a null is returned, and an InvalidCastException is not thrown. Because of this, you should always check the result for null.

This operator does not work with user-defined conversions (both explicit and implicit). A user-defined conversion method extends one type to allow it to be converted to another type. This is done by adding a method, such as the following, to a class or structure:

 public struct MyPoint {     public static explicit operator MyPoint(System.Drawing.Point pt)     {         // Convert a Point structure to a MyPoint structure type.         return (new MyPoint( ));     } } 

This method allows a System.Drawing.Point structure to be cast to an object of type MyPoint. Due to the use of the explicit keyword, the cast must be explicitly defined:

 System.Drawing.Point systemPt = new System.Drawing.Point(0, 0); MyPoint pt = (MyPoint)systemPt; 

If you attempt to use the as operator in a user-defined conversion, the following compiler error is shown:

 Cannot convert type 'MyPoint' to 'Point' via a built-in conversion 

This type of conversion does not work with unboxing conversions, either. An unboxing conversion converts a previously boxed value type to its original value type, such as with the following code:

 int x = 5; object obj = x;         // Box x int originalX = obj as int; // Attempt to unbox obj into an integer. 

If you attempt to use the as operator in an unboxing conversion, the following compiler error is shown:

 The as operator must be used with a reference type ('int' is a value type) 

This is illegal because as indicates that the cast cannot be performed by returning null, but there is no such thing as a null value for an int.

The as operator cannot be used with a type parameter T when T could be a struct, for the same reason as previously mentioned. The following code will not compile:

 public class TestAsOp<T> {     public T ConvertSomething(object obj)     {         return (obj as T);     } } 

because T could be anything since it is not constrained. If you constrain T to be only a reference type as shown here:

 public class TestAsOp<T>          where T: class {     public T ConvertSomething(object obj)     {         return (obj as T);     } } 

your code will compile successfully, since T cannot be a struct.

See Also

See Recipes 3.13 and Recipe 3.15; see the "( ) Operator," "as Operator," and "is Operator" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net