I know the function of this keyword, but I would like to know how it works on a lower level.
Which one is faster? And do they always yield the same result? If they do, why are there two different ways?
// Is there an overhead? An internal try catch?
Class123 obj = someobject as Class123;
if (Class123 != null)
{
//OK
}
or
Class123 obj = null;
if (someobject is Class123)
{
obj = (Class123)someobject;
}
To set a few things straight:
Type casting should be done when you are sure the object is of the type you're casting to. It can be null (in that case, null will be returned, unless it is a value type you're casting to)
When you are not sure, the "as" operator can be used. When the object is not castable, or the object is null, null will be returned.
The "as" operator translates to a dedicated IL statement (isinst), while a type cast translates to the castclass IL statement, so it is built into the runtime. The compiler simply emits the correct IL statement.
This question has already been answered well, however so far it has been missing hard numbers.
The figures consistently come back in these proportions
I want to point out that the only conclusion to take from these figures is that from a performance point of view, there is very little to be gained by choosing one of these methods over the other. There's a very little in the difference for a single call (where very little tends to zero). That said, "as" is faster :)
After that, the above figures mostly stand to reason.
"As" takes longer on failure than it does on success. On success nothing happens, the value can be used as is, or simply copied. On failure it requires a jump to copy a null reference.
"Cast" is faster on failure, one call to "is" and it doesn't do any more. On success it's much slower, it has the over head of the call to "is" and then the cast.
However I'm surprised that Cast on failure takes longer than AS failure
Edit
As requested, figures for cast in a try / catch block
The code that produced the first set of figures
According to MSDN: as (C# Reference):
The first variant (as operand) ...
... compiles to this IL code:
... and the second variant (is operand + cast) ...
... compiles to this IL code:
... so you see the only difference is the additional
castclass
code in lineL_0038
.as may be faster because only needs to ckeck the type once while is + cast need to check the type twice.
There's no internal try-catch happening when using the
as
keyword. The functionality is built in to the compiler/CLR, as far as I know, so the type check is implicit and automated.Simple rule:
Use a direct cast when you always expect the object to have a known type (and thus receive a helpful error if it is by chance of the wrong type). Use the
as
keyword when the object is always of a known type.The reason for the existance of the
as
keyword is purely for the convenience of the programmer (although you are correct in suggesting that a try-catch would be slower). You could implement it yourself manually as such, as you point out:This highlights the fact that the 'as' keyword is primarily there for the purpose of conciseness.
Now, the performance difference between the two is likely to be negligible. The
as
keyword is probably marginally slower because of the type check, but this is unlikely to affect code in the vast majority of situations. As oft said, premature optimisation is never a wise thing to be doing. Benchmark if you really wish, but I would advise just to use whichever method is more convenient/appropiate for your situation, and not worry about performance at all (or later if you absolutely must).