327. About as and is+cast - part 2

בהמשך לפעם הקודמת –

גם אם לא מעניין אתכם שהקוד הבא:

1
Shape shape = obj as Shape;

יותר מהיר מהקוד הבא:

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

(ובצדק)

כדאי לדעת למה עדיף להעדיף את הקוד הראשון על פני השני.

הסיבה הראשונה היא קריאות: יותר קל לקרוא את האופרטור as, מאשר את הקוד מטה.

הסיבה השנייה, שהיא טיפה מפתיעה אפילו היא Thread safety:

אם obj הוא משתנה לוקאלי של פונקציה, אין הבדל בThread safety בין שתי הגישות. לעומת זאת, אם הוא Member של המחלקה, אז יש הבדל:

1
Shape shape = mObj as Shape;

לעומת

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

מה ההבדל?

במימוש הראשון, מאחר ומדובר בפקודת IL יחידה, מתקיים שהפעולה אטומית, כלומר mObj לא יכול להשתנות פתאום.

במימוש השני, לעומת זאת, יכול להיות שאנחנו נכנס לif ובינתיים בThread אחר ישנו לנו את הערך של המשתנה, ואז ההסבה תכשל!

זה אמנם מקרה נדיר (שמבצעים Cast לMember של המחלקה), אבל כדאי להכירו.

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

שתף