Sign in to follow this  
bilsa

[.net] is & as operators?

Recommended Posts

Hi! When I moved from c++ to c# i immediately fealt a relief that c# has build in rtti, and that there is no need for enabling rtti and dynamic_cast. But then again, now that it feels so native to use the "is" and "as" operators i'm concerned about that I'm using it everywhere :( For eg. I often used some kind of rtti like an enum for types: enum SOME_TYPE { SOME_1, SOME_2, etc... } Now i tend to make a specific class for SOME_1, SOME_2 etc... eg. SOME_TYPE t = new SOME_1(); SOME_1 some_1_t = (t as SOME_1); if(some_1_t) { } And my concernes are about the performance of those operators. I have been testing some "benchmarks" and it seemed that the overhead of adding the typecast was like adding a function call in the loop. Anyone have some info on the performance of those operators? thx!

Share this post


Link to post
Share on other sites
First of all: as does only work for reference types and not for value types like enums.

Now back to topic: generally it's better not to have to (down-)cast. I.e., try to design your program in such a way that downcasts happen as rarely as possible. With .NET versions prior to version 2 that was not always as easy to avoid, e.g. because the standard collections only held object-references. With .NET 2 and generics there is much less need for down-casts. (btw. downcast means to cast from a base type to a derived type, e.g. object to string).

Code like this...

public void DoIt(Object obj) {
if(obj is ClassA) {
ClassA foo = (ClassA)obj ;
// do something with foo
} else if (obj is ClassB) {
ClassB bar = (ClassB)obj;
// do something with bar
}
//....
}



...can almost always be avoided by using object oriented techniques, mostly related to some virtual method calls. Look for existing Design Patterns that allow a maximum of abstraction (and elegance) in your code.

Sidenote: if you really have to check the type of an object and a cast, pref


public void DoIt(Object obj) {
MyClass mc = obj as MyClass;
if(mc != null) {
//...
}
}


over


public void DoIt(Object obj) {
if(obj != null && obj is MyClass) {
MyClass mc = (MyClass)mc;
}


The first method is cleaner and faster. But again, keep in mind: downcasts should be avoided.

Regards,
Andre

Share this post


Link to post
Share on other sites
What exactly is the 'as' operator, and why should I want to use it over the (OtherType) operator? And indeed, what's the difference in speed?

Share this post


Link to post
Share on other sites
The 'as' checks the type and returns null if it is not of the requested type.
A cast forces type conversion and will throw an exception if the types do not match.

It's all in the specs...

Cheers

Share this post


Link to post
Share on other sites
"as" tries to cast the object to the type specified. If the cast is not possible it returns null. (MyType) throws an InvalidCastException if the cast fails.

Note: Don't expect the "speed advantage" mentioned to have any impact on your program. It is tiny tiny tiny tiny. The comparison below has very(!) little practical importance. Choose the type of cast that produces the best readable code.

The speed advantage is quite simple (and quite small): if you use "is" and a (MyType)-cast, you have two type-checks (one done by "is" and one done by the actual cast). With "as" there's only one type-check.

I've read somewhere (don't pin me on that) that "as" is even slightly faster than only the direct (MyType)-cast.

On the other hand, you (might) have to check the result of as if it is null if you are not sure whether the cast has worked. Often though you have to check a reference on null anyway, so you can do both at once. In any case, a failed cast with "as" (resulting in a null reference being returned) is much cheaper than a failed (MyType)cast, which causes an InvalidCastException.

One disadvantage of "as" is that it can only be used for reference types as it has to be able to return null, a value not allowed for value-types (except they are .NET 2 nullable, but that's another story).


Regards,
Andre

Share this post


Link to post
Share on other sites
Thx guys!

Yeh, I know that the as operator is faster than the is + cast.

From what you have told me, it seems like the as operation is quite a fast one?

I have checked many design patterns to suit my needs... the most appropriate was the visitor pattern. Though it ended up even slower than the as operation, since there are two additional function calls - One normal + one virtual.

thx guys!

Share this post


Link to post
Share on other sites
Yes, of course the additional function call is slower - but keep in mind that you pay these (very small) costs to get better managable, less error prone code. A value that exceeds the cost by far.

Regards,
Andre

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this