我有一个函数需要三个参数(日,月&年)并创建一个新的dateTime。这是一个公共职能,当三个组合框中的任何一个被放下时,这个公共职能就会被调用。应该抛出异常并处理,如果它不能发生?
单元测试时,我意外地输入了一个无效值,并且抛出了无效的日期时间异常,但这在应用程序中是不可能的,因为组合框仅用有效值预填充。
所以问题是我应该仍然检查和处理函数中的这个异常?
我有一个函数需要三个参数(日,月&年)并创建一个新的dateTime。这是一个公共职能,当三个组合框中的任何一个被放下时,这个公共职能就会被调用。应该抛出异常并处理,如果它不能发生?
单元测试时,我意外地输入了一个无效值,并且抛出了无效的日期时间异常,但这在应用程序中是不可能的,因为组合框仅用有效值预填充。
所以问题是我应该仍然检查和处理函数中的这个异常?
在一般情况下,是的,任何公开的功能可以从任何地方调用,它是很好的做法,从无效输入此外,如果捍卫你的代码,在某些点时间,你肯定知道谁将这些输入提供给函数。
但是,如果输入不好,这个假设的函数可以自己处理不可能的情况,而不会触发异常。
这是比较容易检查输入和遵循的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;
}
对不起,但现在我有一台PC可用于测试即时编写的代码,并且我已修复此代码的第一个版本的一些问题。 – Steve
您不应该阻止或捕捉异常。但是你应该确保在这个“不可能”的情况下真正发生异常。
例外是指被认为不会“正常”发生的“不可能”情况。
例如,如果您调用DateTime
构造函数重载,那么如果输入无效,该构造函数已经会引发异常。如果你认为这不会发生在你的情况下,不要处理这种情况。该框架生成的异常消息很好。
是的,如果函数孤立地允许无效输入被提交,那么函数应该为无效输入引发异常。您不知道未来的开发人员可能会如何或从哪里调用此函数。但另一种更好的选择是对函数进行编码,以便只允许有效的输入。
您可以通过将输入的类型从整数值更改为枚举来完成此操作。创建一个月枚举
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.MinDate
到DateTime.MaxDate
范围之外的年值)
众所周知的模式我看到了太多_impossible situation_发生。 – Steve
我不明白 你说**单元测试时我意外地输入了一个无效值** 如果**组合框仅用有效值预填充**,您是如何输入无效值的? – Youssef13
这就是让我担心的事情!只是想知道什么是最佳实践,而不是不必要的过于复杂的方法 – user5467760