Operatorii is si as

Costul operatorilor as is is

static void Main(string[] args)
{
object obj = new string('s', 1);
IsDemo(obj);
AsDemo(obj);
ExplicitDemo(obj);
}
 static void IsDemo(object str)
{
string local = null;

if (str is string)
{
local = (string)str;
}
}

.method private hidebysig static void IsDemo(object str) cil managed
{
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] string local,
[1] bool CS$4$0000)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: ldarg.0

-- parametrul este incarcat si se testeaze daca este de tip System.String

IL_0004: isinst [mscorlib]System.String
IL_0009: ldnull

-- se incarca pe stiva rezultatul operatiei IL_0004 > IL_0009 (in acest caz e 1)

IL_000a: cgt.un
IL_000c: ldc.i4.0
IL_000d: ceq

-- se calculeaza IL_000a == IL_000a (adica 1 == 0) si se pastreaza rezultatul in loc.1

IL_000f: stloc.1
IL_0010: ldloc.1

-- daca este adevarat (1 == 0) se sare la instructiunea IL_001c, in acest caz nu se sare

IL_0011: brtrue.s IL_001c
IL_0013: nop
IL_0014: ldarg.0

-- castul e sigur si se poate face fara aruncarea exceptiei
InvalidCastException

IL_0015: castclass [mscorlib]System.String
IL_001a: stloc.0
IL_001b: nop
IL_001c: ret
} // end of method Program::IsDemo

static void AsDemo(object str)
{
string local = str as string;
}

.method private hidebysig static void AsDemo(object str) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init ([0] string local)
IL_0000: nop
IL_0001: ldarg.0

-- se testeaza daca clasa obiectului incarcat la IL_0001 este un tip derivat al clasei System.String (System.String este derivat din System.String); daca in loc de System.String ar fi fost o interfata testul se rezuma la faptul daca clasa obiectului implementeaza respectiva interfata. In caz de succes se va face castul la System.String. Altfel este incarcat null. Daca obiectul in sine e null, la fel este incarcat null. Nici o exceptie nu e aruncata la runtime (doar la compilare in cazul in care tipul clasei sau interfetei nu este cunoscut de catre compilator se va da o exceptie TypeLoadException)

IL_0002: isinst [mscorlib]System.String
IL_0007: stloc.0
IL_0008: ret
} // end of method Program::AsDemo

static void ExplicitDemo(object str)
{
string local = (string)str;
}

.method private hidebysig static void ExplicitDemo(object str) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init ([0] string local)
IL_0000: nop
IL_0001: ldarg.0

--Se incearca a se face castul obiectului la clasa System.String. In caz de testul e fara succes va fi aruncata exceptia InvalidCastException. In caz ca obiectul asupra caruia se face castul e null, operatia de cast se considera OK si e returnat noul obiect ca referinta nula (adica null).

IL_0002: castclass [mscorlib]System.String
IL_0007: stloc.0
IL_0008: ret
} // end of method Program::ExplicitDemo

valoarea medie la fiecare 10 000 iteratii in nanosecunde
Cast cu "is"Cast cu "as"Explicit castString de test
610.21722034504451.766355779854749.7828634644906a
21.483177331197113.912382719032712.3200015644446aa
20.226034314417113.940319230516712.3758745874126aaa
21.455240819713113.912382719032713.2698429549007aaaa
20.253970825901113.940319230516712.3479380759286aaaaa
20.198097802933115.225398758780813.3257159778687aaaaaa
20.253970825901114.024128764968712.3758745874126aaaaaaa
20.281907337385113.968255742000712.4038110988966aaaaaaaa
20.198097802933113.940319230516712.3758745874126aaaaaaaaa
20.253970825901113.968255742000713.7447636501287aaaaaaaaaa

Comments

Popular posts from this blog

IIS 7.5, HTTPS Bindings and ERR_CONNECTION_RESET

Verify ILogger calls with Moq.ILogger

Table Per Hierarchy Inheritance with Column Discriminator and Associations used in Derived Entity Types