Linq החיסרון של MAX לאיתור הערך הגדול ביותר ברצף.
-
לפני תקופה התדיינו פה על Max לעומת OrderByDescending + First.
במהלך הדיון כתב @aaron-1 ככה@Aharon-0 כתב באלגוריתם: סינון מערך (#C):
@קומפיונט לא כדאי להשתמש ב max, מספיק שערך אחד null וזה מחסיר תוצאה שגויה
אני לא הבנתי את זה (כי זה עובד מצויין גם עם ערך null) ודרשתי הבהרות למשפט הזה.
@aaron-1 לא הסביר את עצמו (אולי כי לא היה לו כח ליהזכר מה החסרון שהיה לו ולהתנצח). אני כעת חושב שהבנתי את כוונתו. אני סבור שהוא זכר שנזרקת שגיאה בגלל רצף ריק, כלומר "מספיק פעם אחת שהרצף ריק והקוד ייכשל". זאת לעומת הדרך של OrderBy + FirstOrDefault שתעבוד טוב.
הפונקציות Max/Min מחזירות שגיאת "InvalidOperationException: Sequence contains no elements", כאשר הרצף ריק.
זה מאוד מתסכל, כי לרוב הMax יידרש בשרשור לאיזה Where שלגיטימי לגמרי שלעיתים יהיה ללא כל התאמה, בדרך כלל נרצה שהMax יהיה ריק (בעצם שיחזיר Nullable) או אפס במקרה של מספר (שבמבט אנושי נחשב אצלנו מינימום מוחלט במקום -2147483648)
למרות התסכול למה מקרוסופט כאלה מעצבנים, אחרי מחשבה ברור שזה נכון לזרוק שגיאה, כי הערך הדיפולטי של int למשל הוא 0, וזה יכול להתפרש כמקסימום אמיתי כי 0 הוא ערך בהחלט גבוה ביחס למינוס. מה שהיה מתבקש זה MaxOrDefault וזה אפשר להשיג על ידי קומבינה כמתואר כאן. -
@dovid הבעיה היא שאם Max יחזיר ערך דיפולטיבי למערך ריק, זה תוצאה שלא ברור מה המשמעות שלה, כי יכול להיות שהערך המקסימלי הוא 0, וגם יכול להיות שהמערך ריק, זה מה שצריך למנוע על ידי זריקת השגיאה.
זה רעיון שנמצא בהרבה פונקציות, נגיד אם אנחנו רוצים את האיבר הראשון במערך ונקרא ל-
First
אז נקבל שגיאה אם המערך ריק. אם זה יחזיר ערך דיפולטיבי זה גם יהיה דו משמעותי, או שהמערך ריק, או שהאיבר הראשון הוא דיפולטיבי.בקשר לאפס והמינוס, אני לא חושב שזה באמת הסיבה, והראיה שלי כי במערך של
uint
הערך הנמוך הוא 0 וגם שם נזרקת שגיאה. -
בMin/Max לא עשו מימוש לפי סוג, אלא מימוש גנרי לכל IComparable.
אם תמיד הערך המינימלי של IComparable היה זהה לdefault של אותו ערך, אני סבור שהיה הגיוני שהמפתח יקבל את זה ולא יהיה אכפת לו אם זה הערך הכי גבוה באמת, או שפשוט לא היו ערכים בכלל (מבחינתי זה בעצם אותו משפט).
ככה זה בעצם בSum למשל, ברור שהסכום של אפס איברים הוא אפס. למרות שאפס יכול להיות גם סכום של איברים רבים עם ערכים כמו -50 ו+50 אבל עדיין אפס זה באמת התוצאה הנכונה ולא רק שומר מקום לnull, כי יש איזון מוחלט.
אבל אני מקבל את מה שאתה אומר שזה ערך לא בהכרח צפוי, ייתכן שהצדק עמך. -
@dovid יש הבדל ברור בין Sum ל-Max, כשקוראים ל-
Sum
על מערך ריק התוצאה היא 0, כי זה באמת הסכום הכולל של כל הערכים במערך, אבל בקריאה ל-Max
על מערך ריק, החזרה של ערך דיפולטיבי תהיה שגויה, כי זה בעצם אומר לך שהערך המקסימלי במערך הוא 0, וזה לא נכון כי אין בכלל ערך מקסימלי, ולכן התוצאה היאInvalidOperationException
.