326. About as and is+cast

דיברנו כבר בעבר על האופרטורים ששמם as וis. (טיפ מספר 12)

אמרתי שכתיבה של as היא שקולה לבדיקה של הType המתאים באמצעות is ואז קריאה להסבה. עם זאת, אם נסתכל על הקוד IL המקומפל של שתי הקריאות:

1
2
3
4
5
6
Shape shape = null;
if (obj is Shape)
{
shape = (Shape) obj;
}

מתקמפל ל

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
L_0003: ldnull
L_0004: stloc.1
L_0005: ldloc.0
L_0006: isinst Shape
L_000b: ldnull
L_000c: cgt.un
L_000e: ldc.i4.0
L_000f: ceq
L_0011: stloc.2
L_0012: ldloc.2
L_0013: brtrue.s L_001e
L_0015: nop
L_0016: ldloc.0
L_0017: castclass Shape
L_001c: stloc.1
L_001d: nop
L_001e: ret

ואילו השורה הבאה:

1
Shape shape = obj as Shape;

מתקמפלת ל

1
2
3
4
L_0003: ldloc.0
L_0004: isinst Shape
L_0009: stloc.1
L_000a: ret

מה שאנחנו רואים כאן זה משהו מעניין: הפעולה isinst היא פעולת IL הבודקת אם המשתנה שלנו הוא מסוג מסוים.

במקרה ראשון, אנחנו רואים שמתבצעת הפעולה, ולא עושים כלום עם הערך, אבל במידה והוא לא null, מבצעים הסבה לטיפוס של Shape.

במקרה שני, אנחנו רואים שפשוט מוכנס ערך המשתנה למשתנה השני!

הסיכום הוא שלמרות שמדובר בפעולות שקולות, הרי ששימוש באופרטור as הוא חסכוני יותר. זוהי כמובן מיקרו-אופטימיזציה שכנראה לא תהיה צוואר בקבוק בתכנית, אבל מעניין לדעת שפעולה זו מהירה יותר מהפעולה השקולה לה.

המשך יום מוסב לטובה!

שתף