Tuesday, 3 June 2008

Casting, 'is' and 'as' in C#

I was giving a course for a gaming company who were understandably interested in performance issues. One of the things discussed was the relative performance of traditional casting versus is and as, so I had a play.

The general idea is that you have a reference variable of a base class type, which may be referring to an object of a derived class. This derived class has additional members which you wish to use, so you need to have a reference of the derived class type. For example:
BaseClass b;
...
DerivedClass d = b;
d.AMethodOnlyDerivedClassHas();

And of course the second line above will be thrown out by the compiler as BaseClass is less than DerivedClass in hierarchy terms.

A C-style cast could be used, for example:

DerivedClass d = (DerivedClass)b;

If you definitely know that b refers to a DerivedClass object then this is the fastest technique, about 5% faster that using ‘as’. But if b does not refer to a DerivedClass object (or an object of a class derived from it) then an exception is thrown, which is extremely expensive.
When b may or may not refer to a DerivedClass object, ‘as’ is useful as it gives null when the object is not the expected class, for example:

DerivedClass d = b as DerivedClass;
if ( d != null )
{
d. AMethodOnlyDerivedClassHas();
...

This technique allows us to test and cast simultaneously. Although it is a bit slower if the object is the tested-for type, it is enormously faster (>200 times) than catching the exception that the C-style cast throws.

‘as’ is widely used because it allows us to combine the testing with the assignment to a reference of the correct type. ‘is’ can be used just to perform the test, for example:

if ( b is DerivedClass )
...
And in fact ‘is’ and ‘as’ both use the same CLR code, so cost the same. Don’t do this though:

if ( b is DerivedClass )
{
DerivedClass d = b as DerivedClass;
d. AMethodOnlyDerivedClassHas();

as you end up calling the same CLR support code twice.

An alternative would be to compare types, for example:

if ( b.GetType() == typeof( DerivedClass ) )

This is about 10 times as slow as using ‘as’ or ‘is’, but allows an exact comparison rather than the ‘at least’ comparison used by ‘as’ and just about everything else. In practice this is probably not useful though.

4 Comments:

At 24 December 2015 at 11:26 , Blogger John Peter said...

Great Article
C# Training
C# Training


C# Online Training
C-Sharp Training
Dot Net Training in Chennai
.Net Online Training

 
At 23 March 2016 at 10:41 , Blogger deeksha said...

This blog is useful and informative it is really interesting thanks for sharing this information it is really nice and good too.


dotnet training in chennai

 
At 12 December 2016 at 09:12 , Blogger Unknown said...



Thanks for posting this useful content, Good to know about new things here, Let me share this,cisco ucs training

 
At 12 December 2016 at 09:18 , Blogger cisco ucs training said...



Thanks for posting this useful content, Good to know about new things here, Let me share this,cisco ucs training

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home