A better Safe Cast using Generics

My blog has moved. You can view this post at the following address: http://www.osherove.com/blog/2005/11/9/a-better-safe-cast-using-generics.html
Published Wednesday, November 09, 2005 12:38 PM by RoyOsherove
Filed under:

Comments

Wednesday, November 09, 2005 11:10 AM by Julian M Bucknall

# re: A better Safe Cast using Generics

Roy

The boxing issue is fairly trivial. Much worse is the double type-checking. Type-checking is heavy-duty in .NET. The "is" operator will invoke type-checking, and then the cast will then invoke the same type-checking.

I think I'd rather write the code this method replaces.

Cheers, Julian

Wednesday, November 09, 2005 2:44 PM by Ron Buckton

# re: A better Safe Cast using Generics

I agree with Julian, doing an _is_ and then an _as_ or a _castclass_ is more expensive in the msil and tools like code analysis (FxCop) may yell.

The _as_ keyword is always going to be the better choise in C# (and TryCast in VB.NET) for reference types.

If you want to test for a value type with as in 2.0 use ?. e.g.

void Foo(object o)
{
int? a = o as int?;
if(a != null)
{
DoSomething((int)a); // or DoSomething(a.Value);
}
}

(With the RC and RTM releases, _as_ works with Nullable<>, as well as the coalesce operator ?? works with reference types)
Wednesday, November 09, 2005 5:29 PM by Roy Osherove

# re: A better Safe Cast using Generics

Rob, Julian, Thanks for mentioning this.
I agree that the native syntax for nullability chekcing will outperform this code.
Think of this code as an exercise in Generics. In fact, I'd probably use this code and optimize for efficieny at a later time, when it's needed. That wasy I can use the same syntax for both value types and reference types.
(Unless i'm at a place where I *know* this will be a problem sucjh as tight loops that need to run fast on a lot of objects)
Wednesday, November 09, 2005 10:41 PM by Ron Buckton

# re: A better Safe Cast using Generics

Roy,

Its not just about performance though. The _as_ keword is used to perform a cast without an exception, returning null if the cast was not possible. Since a ValueType has no concept of null _as_ would not work by default. The above method would return default(T) rather then null, giving you no way to assure that the value supplied to the _as_ actually *could* be safely cast to the supplied type.

Through the use of Nullable<> however, you then gain the ability to perform the null test, and the compiler for C# has been designed to handle using a nullable ValueType with _as_. That way you can use the same syntax as a ref type and still have the null test.

This method then becomes the most consistent as well as does not incur a cost to box the value.
Thursday, November 10, 2005 1:15 AM by Roy Osherove

# re: A better Safe Cast using Generics

Ron, yes. There is a slight difference in behavior there, isn't there? :)
A simple change such as returning null if the cast won't work instead of default would change this into the same behavior as "as".
I'll update teh post to reflect this fact.
Sunday, November 13, 2005 3:57 AM by Ernst Kuschke

# re: A better Safe Cast using Generics

It would be cool to do something to a similar effect in .NET 3.0 as an extension method to certain types ;o)