Type conversion in C#

Type conversion (or typecasting) is the technique to change an entity from one data type into another. In general there are two types of type conversion; implicit and explicit conversion. This post tells about type conversion in C#.NET and the performance issues.

Implicit conversion

Implicit conversion (or coercion) is automatic type conversion by the compiler. In C# it does not require a special syntax because the type conversion is safe and no data will be lost. In the following example the value of an integer is stored in a long. This is safe because an integer is 4 bytes (on a 32 bit computer), and a long is 8 bytes. So every value that fits in an integer fits in a long. For a complete conversion table see this page.

It is also possible to cast a derived class to a base class without using a special syntax.

Explicit conversion

Instead of implicit conversion explicit conversion (or casting) is not done by the compiler. It is explicitly defined in the application (i.e. it requires a cast operator). There is a possible risk of losing data when the source and destination have a different size or when the source is converted to a base class. Example:

This example will not compile without the explicit cast operator since a double fits not in an integer. Also the value will lose its precision since an integer does not store decimal values. On this page you can find an explicit number conversion table.

User-defined conversion

In C# it is possible to create your own methods for implicit and explicit conversion. For more information see this article.

Helper functions

The .NET framework has various helper functions for conversion. For example System.Convert and the Parse method of various types (e.g. Int32.Parse).

Boxing and unboxing

C# provides a unified type system. All types are derived from the type “object”. It is possible to convert for example an integer to the type object (boxing) and back (unboxing). The is keyword checks if an object is compatible with a specific type. Example:

“Cast” versus “as”

The as operator is often used for type conversion, and it works more or less the same as the cast prefix:

The difference between these two types of conversion is that the first will throw an exception and the second will return null when the conversion is incorrect:

However, this is not the only difference (see this post by Eric Lippert). When you have a user-defined conversion from class A to B, the cast operator (B)A will run the user-defined conversion while the “as” operator will not. The “as” operator will only consider reference, boxing and unboxing conversions. Like Eric says:

  • As: “I don’t know if this conversion is legal or not; we’re going to give it a try and see how it goes.”
  • Cast: “I am certain that this conversion is legal and I am willing to take a runtime exception if I’m wrong.”
  • As: “I want to know what this object *really is*, not what it is convertible to by some representation-changing specially-defined conversion rule.”
  • Cast: “Convert this thing using whatever crazy mechanism you need to do to make it work.”

Performance

This article by Emilio Guijarro gives a good explanation about performance of the cast and “as” operator. He concludes the “as” operator is about 5 times faster than the cast operator. The performance is only going to matter in the million number of casts, and then the performance problem is probably why you need so many cast operations.

Why (not) to use “as”

As said before the “as” operator returns null when the conversion is incorrect. When using this piece of code you can not check if the original object was null:

This program will write “Incorrect conversion” while the cast conversion didn’t throw an exception. Also the “is” operator does not help in this case since it returns false when the object is null. A correct pattern could be:

References

Leave a Reply

Your email address will not be published. Required fields are marked *