241. Dynamic and binary operations

לפעמים היינו רוצים לכתוב קוד כזה:

1
2
3
4
5
public static T Average<T>(T first, T second)
where T : IAddable<T>
{
return (first + second)/2;
}

למרבה הצער הקוד הזה לא מתקמפל ובטח גם לא עובד.

הסיבה לכך היא שאי אפשר להכריח Operator Overload בממשק. (ראו גם טיפ מספר 196)

עד Framework 4.0 לא היה אפשר לפתור את זה בצורה פשוטה.

כמו קריאות דינאמיות אחרות שכבר ראינו, יש תמיכה בDynamic לאופרטורים בינאריים:

נוכל לכתוב את הקוד הבא:

1
2
3
4
public static dynamic Average(dynamic first, dynamic second)
{
return (first + second) / 2;
}

מה שקורה כאן, כרגיל, זה שבזמן ריצה מפוענחים הפרמטרים והקריאה לאופרטור.

הבעיה פה שזה ממש לא Compile safe, ולמשל הקוד הבא גם יתקמפל:

1
dynamic invalidAverage = Average("Text", 2);

למרות שברור שזה לא אמור להתקמפל.

אפשר למנוע את זה ע"י שימוש בGenerics:

1
2
3
4
5
6
public static T Average<T>(T first, T second)
{
dynamic firstNumber = first;
dynamic secondNumber = second;
return (firstNumber + secondNumber) / 2;
}

זה מונע מאיתנו לקרוא לפונקציה כאשר לא מתקיים ששני הפרמטרים וערך ההחזר שווים.

זה אמנם לא מכסה את כל המקרים הבעייתיים של קריאה לפונקציה, אבל מונע חלק נכבד מהם.

המשך יום דינאמי טוב

שתף