Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the "as" keyword work internally?

Tags:

c#

clr

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;
}
like image 594
Felipe Pessoto Avatar asked Jun 05 '09 11:06

Felipe Pessoto


1 Answers

According to MSDN: as (C# Reference):

The as operator is like a cast operation. However, if the conversion is not possible, as returns null instead of raising an exception. Consider the following expression:

expression as type

It is equivalent to the following expression except that expression is evaluated only one time.

expression is type ? (type)expression : (type)null

The first variant (as operand) ...

string str1 = strAsObject as string;
if (str1 != null)
{
    this.blabla(str1);
}

... compiles to this IL code:

L_0009: ldloc.1 
L_000a: isinst string
L_000f: stloc.2 
L_0010: ldloc.2 
L_0011: ldnull 
L_0012: ceq 
L_0014: stloc.s CS$4$0000
L_0016: ldloc.s CS$4$0000
L_0018: brtrue.s L_0024
L_001a: nop 
L_001b: ldarg.0 
L_001c: ldloc.2 
L_001d: call instance void TestWinFormsApplication001.Form1::blabla(string)
L_0022: nop 
L_0023: nop 

... and the second variant (is operand + cast) ...

if (strAsObject is string)
{
    string str2 = (string) strAsObject;
    this.blabla(str2);
}

... compiles to this IL code:

L_0024: ldloc.1 
L_0025: isinst string
L_002a: ldnull 
L_002b: cgt.un 
L_002d: ldc.i4.0 
L_002e: ceq 
L_0030: stloc.s CS$4$0000
L_0032: ldloc.s CS$4$0000
L_0034: brtrue.s L_0047
L_0036: nop 
L_0037: ldloc.1 
L_0038: castclass string
L_003d: stloc.3 
L_003e: ldarg.0 
L_003f: ldloc.3 
L_0040: call instance void TestWinFormsApplication001.Form1::blabla(string)
L_0045: nop 
L_0046: nop 

... so you see the only difference is the additional castclass code in line L_0038.

like image 120
ulrichb Avatar answered Sep 21 '22 15:09

ulrichb