היי,
במדעי המחשב קיים מושג שנקרא covariance ומושג מקביל שנקרא contravariance.
הסבר פשוט של המושג הוא הבא:
נניח שיש לנו פונקציה $ f $ שפועלת על Typeים (מקבלת Type ומחזירה Type).
נאמר שהיא covariant אם לכל טיפוס $ B $ שיורש מטיפוס $ A $, מתקיים $ f(B) $ יורש מ$ f(A) $.
כתיב:
$ B : A \implies f(B) : f(A) $
לדוגמה,
נניח שיש לנו את הTypeים הבאים
|
|
טבעי לצפות שהפונקציה שמעבירה כל טיפוס $ T \mapsto \text{List}[T] $ תהיה covariant, שהרי היינו מצפים ש List<Circle> ירש מList<Shape>שהרי Circle יורש מShape.
אבל דבר זה גורר סתירה, כי אז נוכל לכתוב את השורות הבאות:
|
|
מה הבעיה בשורות אלו? הכנסנו לרשימה של מעגלים, משולש!
מאחר ולא רצו שנחטוף exception בזמן ריצה, החליטו שList<T> לא יהיה covariant (ולא רק הוא), לכן השורה הראשונה של ההשמה, בכלל לא מתקמפלת.
הסיבה לכך היא שאחד הדברים שgenerics מעניקים לנו זה type safety, ומונעים מאיתנו לעשות שטויות כאלה כבר בזמן קימפול.
עם זאת, covariance כן ממומש בC#, ואפילו בC# 1.0:
אם ניקח את הדוגמה הקודמת ונשנה אותה קצת:
|
|
השורה הזאת מתקמפלת. כלומר מתקיים ש $ T \mapsto T[] $ הוא covariant.
במילים אחרות
|
|
מה יקרה אם ננסה לעשות משהו כמו קודם?
|
|
נקבל exception בזמן ריצה
"Attempted to access an element as a type incompatible with the array."
המסקנה היא שצריך מאוד להיזהר עם covariance של מערכים בC#.
הערה: Covariance של מערכים בC# עובד רק על Reference Types: למשל לא מתקיים
|
|
שבוע מעולה