如果不能发生异常,是否应该抛出并处理?

时间:2017-08-27 13:52:02

标签: c# validation exception-handling

我有一个带三个参数(日,月和年)的函数,并创建一个新的dateTime。它是一个公共函数,当三个组合框中的任何一个被删除时会被调用。

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

所以问题是我还应该在函数中检查并处理这个异常吗?

3 个答案:

答案 0 :(得分:2)

一般情况下,是的,任何公共函数都可以从任何地方调用,如果在某个时间点确定谁将输入提供给函数,那么从无效输入中保护代码也是一种好习惯。< / p>

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

检查输入并遵循众所周知的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;
 }

答案 1 :(得分:1)

是的,如果函数单独允许提交无效输入,则函数应该为无效输入抛出异常。您不知道未来的开发人员如何或从何处调用此函数。但另一个更好的选择是对函数进行编码,以便只允许有效输入。

您可以通过将输入类型从整数值更改为Enums来执行此操作。创建月份枚举

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 Enum

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

你可以编写函数来处理31个月,其中只有30天作为下个月的第一个月,2月29日,30日和31日作为3月1,2,3等,以避免对此进行处理无效。然后你的函数的签名将是

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

并且无法传递无效值。 (我估计除了DateIme.MinDateDateTime.MaxDate范围之外的年份值

答案 2 :(得分:0)

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

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

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