[נכתב ע”י דניאל קוגל]
ראינו ביום ראשון שגם struct יכול לממש ממשק, אבל אם נבצע השמה של הstruct לממשק זה, יתבצע boxing.
|
|
באופן דומה, כאשר נגדיר מתודה שמקבלת ממשק:
|
|
ונעביר לה את struct שמממש את הממשק, יתבצע boxing בקריאה למתודה:
|
|
אבל אם נגדיר את המתודה שלנו גנרית עם אילוצים:
|
|
הקומפיילר ידע למנוע את ה-boxing ולקרוא למתודה ישירות:
|
|
המסקנה היא שאפשר להשתמש בGenerics כדי למנוע boxing של struct בקריאה לפונקציה שמקבלinterface.
אם נסתכל על הגוף של המתודה הגנרית, הוא נראה כך:
|
|
כפי שרואים נוספה פקודה של constrained לפני הפקודה callvirt, הסיבה היא שהמהדר לא יודע האם TPrintable הוא value type או reference type אבל הוא כן יודע שצריך להעביר כתובת כלשהי למתודה בתור ה-this שלה מכיוון שמדובר במתודה של ממשק אשר לא יכול להיות סטטית (כלומר חייב להיות לה this).
לאחר שקיבלנו את הכתובת של הפרמטר ודחפנו אותו למחסנית (IL_0000), כאשר אנו קוראים ל-callvirt שלפניו יש constrained אז במידה ו-TPrintable הוא reference type אז על המחסנית בעצם נמצא pointer שמצביע ל-pointer שכן הפרמטר מכיל כתובת ולכן מתבצע dereference כדי שה-this יצביע לאן שצריך וניתן לקרוא למתודה בעזרת Callvirt.
במידה ו-TPrintable הוא value type אז הכתובת של הפרמטר בעצם מכילה את הכתובת של ה-value type וניתן להעביר אותה כמו שהיא למתודה בעזרת Call.
המשך יום גנרי ומובנה