מה הבעיה במתודה הבאה:
-
אני מנסה לכתוב תוכנית לניהול תרומות,
כתבתי את המתודה הבאה שנועדה לחשב את סכום חודשי התרומה עד היום (בתרומה חודשית קבועה):public int SumMonthDonation(DateTime startDonor)//חישוב סך חודשי התרומה בפועל { int sumMonth=0; var today = DateTime.Today;//חישוב התאריך הנוכחי int nowMonth = DateTime.Today.Month; //שמירת מספר החודש הנוכחי int oldMonth = startDonor.Month;//שמירת מספר חודש התרומה int year = CompareYear(startDonor, today); //אם מדובר באותה שנה, אז ודאי החודש הנוכחי גדול יותר מחודש תחילת התרומה if (year == 0) { if (nowMonth != oldMonth) { sumMonth = nowMonth - oldMonth; return sumMonth; } else throw new Exception("This is a new Donation!!"); } //אם יש פער בשנים מחשב את סך חודשי התרומה else if (year != 0) { sumMonth = year * 12; if (nowMonth > oldMonth) { sumMonth += (nowMonth - oldMonth); return sumMonth; } else if (nowMonth < oldMonth) { /*כאשר החודש הנוכחי קטן מחודש תחילת התרומה, סימן שלא עברה שנה מלאה מאז, *ולכן צריך להחסיר את החודשים היתרים שהרי כבר החשבנו 12 חודשים לשנה הזאת*/ sumMonth -= (oldMonth - nowMonth); return sumMonth; } else return sumMonth; }
הבעיה שכשאני עושה build הוא כותב לי את השגיאה הבאה: not all code paths return a value על המתודה הזאת..
אם אני מבין נכון טענתו היא שלא כל חלקי המתודה מחזירים ערך.
אבל אני לא מבין למה הוא מעליל עלי ככה?? הרי כתבתי return עם ערך של int בכל מקום שצריך??פורסם במקור בפורום CODE613 ב26/06/2015 15:09 (+03:00)
-
היה לך if ואז else if אם שתי התנאים לא מתקיימים אז לא יחזור ערך? אז הוא צריך עוד else אחרון.
במקרה שלך זה לא יכול לקרות, אז תוריד את התנאי של שנה שונה מאפס זה בטוח המצב אם התנאי של שווה לאפס לא התקיים
אבל למה שלא תשתמש ב
Microsoft.VisualBasic.DateDiffפורסם במקור בפורום CODE613 ב26/06/2015 17:07 (+03:00)
-
א. יפה מאוד איך שאתה כותב.
ב. הבעיה היא כמו שsoft אמר, מבחינת הקומפיילר ישנם אפשרות לא מוכסה. כי כתבת אם... ואם לא, אז אם... וזהו. מבחינה לוגית יש פה חור למקרה נוסף. רק כמו שsoft אמר, האם השני מיותר. תזכור שבif else אין מצב בעולם ששני הבלוקים במוצעים. אם בוצע הבוק הראשון בגלל שyear היה שווה אפס, לא תהיה כניסה לבלוק הelse וממילא ההתניה year != 0 מיותרת.
ג. soft אמר שיש מתודות מוכנות לבעיה שלך. בעיקרון הפרש בין תאריכים מושג בקלות ע"י חיסור אחד בשני:var hefresh = DateTime.Now - startDonor; Console.WriteLine(hefresh.TotalDays);
השורה הראשונה מגידרה משתנה בשם hefresh שמקבל את חיסור התאריך הנוכחי בתאריך ההתחלה. התוצאה היא מסוג TimeSpan מחלקה שמייצגת "חתיכת זמן". יש לה מתודות רבות: כמה ימים כמה שעות וכו'. רק שאין לה מתודה לכמות החודשים. למה? ומה הבעיה לעשות ימים לחלק לשלושים? כי חודש זה לא שלושים יום אלא בערך, ומה שרוצים לדעת זה לא כמות ימים אלא כמה חודשים ממשיים עברו. ולכן צריך לבדוק כמו שעשית: כמה שנים יש כפול 12 חודשים וגם ההפרש בין תחילת וסוף השנה של התאריכים. הנה דוגמאות: http://stackoverflow.com/a/1526004/1271037 http://stackoverflow.com/a/4639057/1271037.
soft הצביע על מתודה של vb שיכולה להיקרא מC#, שעושה בדיוק את העבודה הזו (http://referencesource.microsoft.com/#Microsoft.VisualBasic/DateAndTime.vb,229), רק שצריך להוסיף בשבילה reference מה שנראה לי מיותר.פורסם במקור בפורום CODE613 ב28/06/2015 13:03 (+03:00)
-
דוד, כל הכבוד על התשובות מאירות העיניים שלך, הלוואי והיה לי אחד כזה בשנותי הראשונות . . .
מה זה DateDif?
אני לא מכיר את שפת ויזואל בייסיק..
ואינני מכיר מתודה שממשת את זה בC#.כתבת את הלוגיקה, אבל השארת פונקציה שעושה חישוב ספציפי, בפעם הבאה שתצטרך חישוב מרווח בין חודשים תעשה העתק-הדבק?
בשם עיקרון ה Reusability היה עדיף שתכין מזה פונקציה כללית, לדוגמה : תן פרמטר נוסף שישמש כ "תאריך עד", תן שם גנרי יותר ותשים בקלאס public static וכו'
ועוד משהו שארכיטקט כתב פה בימים האחרונים, מתכנת צריך לרכוש את אומנות הגיגול, זה חלק מארגז הכלים הבסיסי למתכנת, בגיגול קצר היית מוצא את זה://---------------------------------------------------------------------------------------- // Copyright © 2003 - 2013 Tangible Software Solutions Inc. // This class can be used by anyone provided that the copyright notice remains intact. // // This class simulates the behavior of the classic VB 'DateDiff' function. //---------------------------------------------------------------------------------------- public static partial class Simulate { public enum DateInterval { Day, DayOfYear, Hour, Minute, Month, Quarter, Second, Weekday, WeekOfYear, Year } public static long DateDiff(DateInterval intervalType, System.DateTime dateOne, System.DateTime dateTwo) { switch (intervalType) { case DateInterval.Day: case DateInterval.DayOfYear: System.TimeSpan spanForDays = dateTwo - dateOne; return (long)spanForDays.TotalDays; case DateInterval.Hour: System.TimeSpan spanForHours = dateTwo - dateOne; return (long)spanForHours.TotalHours; case DateInterval.Minute: System.TimeSpan spanForMinutes = dateTwo - dateOne; return (long)spanForMinutes.TotalMinutes; case DateInterval.Month: return ((dateTwo.Year - dateOne.Year) * 12) + (dateTwo.Month - dateOne.Month); case DateInterval.Quarter: long dateOneQuarter = (long)System.Math.Ceiling(dateOne.Month / 3.0); long dateTwoQuarter = (long)System.Math.Ceiling(dateTwo.Month / 3.0); return (4 * (dateTwo.Year - dateOne.Year)) + dateTwoQuarter - dateOneQuarter; case DateInterval.Second: System.TimeSpan spanForSeconds = dateTwo - dateOne; return (long)spanForSeconds.TotalSeconds; case DateInterval.Weekday: System.TimeSpan spanForWeekdays = dateTwo - dateOne; return (long)(spanForWeekdays.TotalDays / 7.0); case DateInterval.WeekOfYear: System.DateTime dateOneModified = dateOne; System.DateTime dateTwoModified = dateTwo; while (dateTwoModified.DayOfWeek != System.Globalization.DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) { dateTwoModified = dateTwoModified.AddDays(-1); } while (dateOneModified.DayOfWeek != System.Globalization.DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) { dateOneModified = dateOneModified.AddDays(-1); } System.TimeSpan spanForWeekOfYear = dateTwoModified - dateOneModified; return (long)(spanForWeekOfYear.TotalDays / 7.0); case DateInterval.Year: return dateTwo.Year - dateOne.Year; default: return 0; } } }
פורסם במקור בפורום CODE613 ב02/07/2015 12:37 (+03:00)