2017-08-27 71 views
0

我有一个函数需要三个参数(日,月&年)并创建一个新的dateTime。这是一个公共职能,当三个组合框中的任何一个被放下时,这个公共职能就会被调用。应该抛出异常并处理,如果它不能发生?

单元测试时,我意外地输入了一个无效值,并且抛出了无效的日期时间异常,但这在应用程序中是不可能的,因为组合框仅用有效值预填充。

所以问题是我应该仍然检查和处理函数中的这个异常?

+1

众所周知的模式我看到了太多_impossible situation_发生。 – Steve

+0

我不明白 你说**单元测试时我意外地输入了一个无效值** 如果**组合框仅用有效值预填充**,您是如何输入无效值的? – Youssef13

+0

这就是让我担心的事情!只是想知道什么是最佳实践,而不是不必要的过于复杂的方法 – user5467760

回答

2

在一般情况下,是的,任何公开的功能可以从任何地方调用,它是很好的做法,从无效输入此外,如果捍卫你的代码,在某些点时间,你肯定知道谁将这些输入提供给函数。

但是,如果输入不好,这个假设的函数可以自己处理不可能的情况,而不会触发异常。

这是比较容易检查输入和遵循的TryParse

public bool TryMakeDateTime(int year, int month, int day, out DateTime date) 
{ 
     date = DateTime.MinValue; 

     if(!IsValidDay(year, month, day)) 
     return false; 

     date = new DateTime(year, month, day); 
     return true; 
} 

public bool IsValidDay(int year, int month, int day) 
{ 
    if(day < 1 || day > 31) 
     return false; 

    if(month < 1 || month > 12) 
     return false; 

    if(day > 30 && (month == 2 || 
        month == 4 || 
        month == 6 || 
        month == 9 || 
        month == 11)) 
     return false; 

    // This is arbitrary, adjust the check to your constraints 
    if(year < 1900 || year > 2099) 
     return false; 

    if(month == 2) 
    { 
     // IsLeapYear cannot handle values below 1 or higher than 9999 
     // but we have already checked the year with more retrictive 
     // constraints. 
     int extraDay = (DateTime.IsLeapYear(year) ? 1 : 0); 
     if(day > (28 + extraDay)) 
      return false; 
    } 
    return true; 
} 
+0

对不起,但现在我有一台PC可用于测试即时编写的代码,并且我已修复此代码的第一个版本的一些问题。 – Steve

0

您不应该阻止或捕捉异常。但是你应该确保在这个“不可能”的情况下真正发生异常。

例外是指被认为不会“正常”发生的“不可能”情况。

例如,如果您调用DateTime构造函数重载,那么如果输入无效,该构造函数已经会引发异常。如果你认为这不会发生在你的情况下,不要处理这种情况。该框架生成的异常消息很好。

1

是的,如果函数孤立地允许无效输入被提交,那么函数应该为无效输入引发异常。您不知道未来的开发人员可能会如何或从哪里调用此函数。但另一种更好的选择是对函数进行编码,以便只允许有效的输入。

您可以通过将输入的类型从整数值更改为枚举来完成此操作。创建一个月枚举

public enum CalendarMonth { 
    NotSet = 0, January = 1, February = 2, 
    March = 3, April = 4, May = 5, June = 6, 
    July = 7, August = 8, September = 9, 
    October = 10, November = 11, December = 12} 

和DAYOFMONTH枚举

public enum DayOfMonth { 
    NotSet = 0, dom1 = 1, dom2 = 2, ....etc., ... dom31 = 31 } 

你可以编写功能在他们只有30天的治疗月31日为第一下个月,和年02月29 ,3月1日至3月30日等,以避免将此视为无效。然后你的函数的签名将是

public DateTime NewDate(DayOfMonth dom, CalendarMonth month, int year); 

它不可能通过它无效的值。 (除了我猜的DateIme.MinDateDateTime.MaxDate范围之外的年值)

相关问题