בהמשך לטיפ היומי של אתמול, נניח שיש לנו delegate כזה
|
|
אבל אנחנו הגדלנו ראש, והצלחנו לממש פונקציית ציור של כל צורה:
|
|
היינו רוצים שנוכל להשתמש בפונקציה של ציור צורה כללית DrawShape, כדי לצייר בפרט מעגל.
שוב, מצד אחד זה נראה כאילו אנחנו צריכים להחליף את החתימה של הפונקציה, כדי שתקבל Shape, או לחלופין ליצור פונקציה שקוראת לה עם החתימה של CircleDrawer, שכל ההבדל היא שהפונקציה מקבלת Circle במקום Shape.
גם כאן, בC# 2.0 חשבו על זה, ונתנו לנו תמיכה בהסבות כאלה ברמת הקוד:
|
|
קצת על contravariance – אם אמרנו שהמשמעות של covariance היא כזאת:
פונקציה $ f $ של Typeים היא covariant אם לכל טיפוס $ B $ שיורש מטיפוס $ A $, מתקיים $ f(B) $ יורש מ$ f(A) $.
כתיב:
$ B : A \implies f(B) : f(A)$
אז המשמעות של Contravariance היא אנלוגית:
פונקציה f של Typeים היא contravariant היא אם לכל טיפוס $ B $ שיורש מטיפוס $ A $ , מתקיים $ f(A) $ יורש מ$ f(B) $:
$ B : A \implies f(A) : f(B)$
שימו לב להבדל הדק, שהיחס בין הירושה לא נשמר, אלא מתהפך.
היינו מצפים, למשל, בעקבות מה שרשמתי למעלה, שאם יש לנו את שני הdelegateים הבאים:
|
|
יתקיים משהו בסגנון
|
|
כי ראינו שאפשר להכניס לתוך CircleDrawer מתודה עם חתימה של ShapeDrawer.
בC# 2.0 אין תמיכה בזה, ולמשל הקוד הבא מתקמפל:
(הפונקציה היא כמקודם)
|
|
יום קונטרה וואריאנטי מצוין