Is, as, cast – what, when and why – Casting in C# 101

By | May 21, 2017

While I can’t say casting is a way to go in C#, it’s a rather common operation. It’s good to know there is more than one way of doing that and the best way depends on current circumstances. 

Explicit Cast

I’m assuming you know what casting is but just to be clear, I mean changing object type like casting an int to long or some kind of JSON to string. It’s common, it happens all the time and sometimes we just need to do that. Let’s start with the most basic case of explicit casting and let’s change int to other numeric types.

There wasn’t any problem of course. So let’s make one.

Now we can’t cast our integer stored in a type of object directly to long. It’s because while we’ve wrapped our value in object type, the compiler still can check stored object type and see it’s Int32, but it won’t check what can we cast Int32 into, that’s entirely up to us.

As keyword

We’ve warmed up, I think everyone should know about basic case scenario. Let’s move to a second way of casting – “as” keyword.

Remember when we’ve tried to cast int in an object to long type and we’ve got an exception?

While it’s safe to catch and handle it, sometimes we would want to cast in the relatively safe way, without any exceptions if something goes wrong. This keyword return object cast as some other type or null if it’s not possible to cast it this way.

For example, let’s peek into LINQ source code, LastOrDefault method to be precise.

This method takes an IEnumerable<T> and returns the last element in the collection (or default value). IEnumerable interface has no idea how much elements are present in the collection so only way it can do this is to enumerate through everything until there’s no next element, it’s inefficient. We can use this method on many types of collections, some of them could, for example, implement the IList interface which has Count property and indexer we could use to access the last element without enumerating through entire collections.

The problem is we don’t know whether our collection implements IList or not. We could try to cast it and catch the exception in case of InvalidCastException but it would not be an elegant way to do that. That’s why we can just assign the result of casting to some variable and just check it for null later.

There is one problem with as keyword. We cannot do this:

Int is a value type, so it cannot be null and as keyword doesn’t return default(T) in a case of failed cast, it’ll always be null and value types in C# can’t be null.

We could, of course, cast to nullable type like that:

But checking if n IS actually an int feels just so much more intuitive.

Is

So let’s check if our n is an integer before we cast it and risk exception.

It’s simple and yet we still need to check and then, if it’s possible to cast our value to chosen type. It’s better that try/catching but it doesn’t look good.

And if you’re using C# 7.0 or later you can make it perfect.

C# 7.0 – Is

This version of C# introduced pattern matching and with it some great syntax sugars. On of them is mentioned keyword. Now we can check anything with is keyword and assign it to a local variable(with the scope limited to this conditional expression) in same conditional expression. Just like that:

And if you’ll ask me it’s a way to go. It’s most clean way in my opinion and if you can use this feature in your project you should do it.

Links

Performance benchmarks for safe cast operators: https://www.danielcrabtree.com/blog/164/c-sharp-7-micro-benchmarking-the-three-ways-to-cast-safely

PS. I’ve finally posted a contact form on this blog recently, the thing that I’ve been forgetting about since I’ve migrated to WordPress. Feel free to reach me with it anytime.