TheDeveloperBlog.com


C# As: Cast Examples

As is a cast. With it, we gain performance and avoid exceptions when a cast is invalid. Null is returned when the cast is impossible. For reference types, the as-cast is recommended. It is both fast and safe.

Tip: We can test the resulting variable against null and then use it. This eliminates extra casts.


Example. To start, this example declares a string variable. It then casts it to the base object class type. Then the object variable is changed to a string with the as-operator. The object is next cast to a StringBuilder.

But: This cast fails—StringBuilder is not a more derived type of the original type of string.

Based on:

.NET 4.5

C# program that uses as-casts

using System;
using System.Text;

class Program
{
    static void Main()
    {
	// Create a string variable and cast it to an object.
	string variable1 = "carrot";
	object variable2 = variable1;

	// Try to cast it to a string.
	string variable3 = variable2 as string;
	if (variable3 != null)
	{
	    Console.WriteLine("have string variable");
	}

	// Try to cast it to a StringBuilder.
	StringBuilder variable4 = variable2 as StringBuilder;
	if (variable4 != null)
	{
	    Console.WriteLine("have StringBuilder variable");
	}
    }
}

Output

have string variable

On success, the newly-typed variable is available. In the program, variable3 is now a string. And we can use it just like any other string, like the original variable1. There is no difference.

However: When you try an incompatible cast, such as with the StringBuilder type, the result of the casting expression is null.

Null

Note: You can test the stored local variable variable4 against the null literal to test for success.


Example 2. The as-cast will not throw an exception if the cast fails, but if you do not check its result, your program will likely fail. Here I cast an object to a List—the cast fails and returns null.

Then: I try to use the null List, which causes an exception. A method cannot be called on a null instance.

Null ListNullReferenceException
C# program that causes NullReferenceException

using System.Collections.Generic;

class Program
{
    static void Main()
    {
	string value = "cat";
	object temp = value;
	List<string> list = temp as List<string>;
	list.Add("dog");
    }
}

Output

Unhandled Exception: System.NullReferenceException:
Object reference not set to an instance of an object.


Performance. The as-cast is sometimes the most efficient way to test for a certain type. You can use the variable after you have a successful cast. There is seldom any reason to use an is-cast before an as-cast.

Is

Here, we test an explicit reference type cast (StringBuilder) against the as-cast. I consistently found that the as-cast in this situation was faster—by almost an entire third of a nanosecond per instruction.

Thus: Using the as-cast is preferable on micro-benchmarks with reference object types.

Local variables used: C#

StringBuilder builder = new StringBuilder();
object item = (object)builder;

Inner loop tested 1: C#

StringBuilder build = (StringBuilder)item;
if (build == null)
{
    throw new Exception();
}

Inner loop tested 2: C#

StringBuilder build = item as StringBuilder;
if (build == null)
{
    throw new Exception();
}

Results

1.28 ns   Explicit cast
0.99 ns   As-cast


FxCop. Excessive casting is a performance complaint in the FxCop static analysis tool. Also, the as-cast avoids throwing an exception on an invalid cast, which in this case makes it much faster than an explicit cast.

FxCop

Instructions. Next we consider the implementation of casts. At the instruction level in the intermediate language, you will see that the as-cast is implemented in terms of the isinst opcode, the same used for the is-cast.

However: The isinst instruction is followed by further instructions. These store the local variable that was received by the ininst code.

And: By storing the local variable, the as-cast results in the overall reduction of cast instructions.

IL

Summary. With "as" we cast reference variables. This cast receives two operands: the variable you want to cast, and the type you are trying to cast to. Then, upon evaluation, it returns the cast variable or null.

Review: The as-cast is an efficient, elegant way to cast. It promotes exception-neutral and less redundant code.