ב-#C יש 2 דרכים לביצוע cast בין טיפוסים.
הראשונה היא הדרך הסטנדרטית והמוכרת:
class Person { }
class Program
{
static void Main()
{
object foo = new Person();
Person bar = (Person)foo;
}
}
ולעומתה, השימוש במילת המפתח "as":
object foo = new Person();
Person bar = foo as Person;
ההבדלים- ניסיון
לבצע קאסט "סטנדרטי" על טיפוסים שאין ביניהם קשר של הורשה/מימוש (למשל
ניסיון לבצע קאסט בין מחלקת Car לבין Apple), יוביל לזריקת שגיאה מסוג
InvalidCastException.
- לעומת זאת, ניסיון לבצע קאסט בלתי אפשרי
באמצעות שימוש במילת המפתח "as" לא יגרום לזריקת שגיאה. בסך הכל מה שיקרה
זה שהפעולה תחזיר null, והתוכנית תמשיך בביצוע כרגיל.
- אם רוצים להיות מעט פדנטים, אז מבחינת ביצועים, "as" הינה מעט פחות מהירה מאשר שימוש בקאסט רגיל.
הבעיהלמתכנתים רבים יש נטייה להשתמש ב-"as" במקומות לא נכונים.
מהו מקום "לא נכון"? כל מקום בו הטיפוס שאנו מבצעים עליו את הקאסט (foo)
חייב להיות מהטיפוס שעליו אנו מנסים לבצע את הקאסט (Person). שלמעשה, מדובר בערך ב-95% מהמקרים.
הרי
נניח ופעולת הקאסט נכשלה. בשימוש ב-as, המשתנה שלנו יתאתחל ל-null
והתוכנית תמשיך לרוץ כרגיל. רק "מאוחר יותר", בפעם הראשונה שמישהו ינסה
לגשת למשתנה הזה, תתעופף שגיאת NullReferenceException שכנראה לא תגיד לנו
שום דבר שלא קשור לקאסט שנכשל לפני 200 שורות קוד.
לעומת זאת, אם היינו
משתמשים בקאסט הרגיל, כבר על ההתחלה היתה נזרקת לנו שגיאת
InvalidCastException שהיתה מספקת לנו את כל המידע הדרוש להבנה מלאה למה
שהוביל לשגיאה.
האלטרנטיבה (והשימוש הנכון) ב-as הוא לבדוק האם הקאסט
הצליח על ידי השוואה ל-null. אבל מן הסתם, לא נרצה לכתוב את הקוד המעייף
הזה בכל פעם שאנו מבצעים קאסט כזה או אחר.
אז מהו "המקום הנכון"?
בכל
מקום בה קיימת אפשרות אמיתית והגיונית שהמופע עליו אנו מנסים לבצע את
הקאסט באמת לא שייך לטיפוס הנכון. ומאוד הגיוני שהקאסט יכשל.
במקרה
כזה, אין סיבה לזרוק שגיאה מאחר ואנו מצפים ומקבלים את העובדה שיתכן
שהקאסט יכשל. לכן במצב כזה עלינו לבדוק אם הקאסט בכלל הצליח.
דוגמה
למצב כזה היא מימוש לפונקציית ה-Equals. כשאנו דורסים אותה, אנו מקבלים
פרמטר מסוג object, כך שלפני שאנו נגשים להשוואת הערכים בין שני המופעים,
אנו בכלל לא יודעים באיזה טיפוס מדובר..
שימוש בקאסט רגיל כאן הוא לא
נכון, כי יתכן שמישהו העביר כפרמטר מופע של טיפוס לא מתאים ... עלינו
לצפות למקרה כזה, ו..."להתנהג בהתאם".