Есть ли более быстрый способ, чтобы просто поймать исключение, как показано ниже?
try
{
date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
// This is an invalid date
}
Есть ли более быстрый способ, чтобы просто поймать исключение, как показано ниже?
try
{
date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
// This is an invalid date
}
String DateString = String.Format("{0}/{1}/{2}", model_.Date.Month, (7 * multiplier) + (7 - dow) + 2),model_.Date.Year);
DateTime dateTime;
if(DateTime.TryParse(DateString, out dateTime))
{
// valid
}
Как указано в GenericTypeTea, этот код не будет работать быстрее, чем у вас сейчас. Тем не менее, я считаю, что вы получаете читаемость.
Если ваша цель состоит в том, чтобы избежать использования исключений, вы можете написать собственный метод проверки:
public bool IsValidDate(int year, int month, int multiplier, int dow)
{
if (year < 1 | year > 9999) { return false; }
if (month < 1 | month > 12) { return false; }
int day = 7 * multiplier + 7 - dow;
if (day < 1 | day > DateTime.DaysInMonth(year, month)) { return false; }
return true;
}
Выполняет большинство тех же проверок, что и используемый конструктор DateTime, - он только пропускает проверку, чтобы увидеть, будет ли результат DateTime меньше, чем DateTime.MinValue или больше, чем DateTime.MaxValue.
Если вы в основном получаете хорошие значения, это, вероятно, будет более медленным: DateTime.DaysInMonth должен делать много тех же вещей, что и конструктор DateTime, поэтому он добавит накладные расходы ко всем хорошим датам.
Хм... подумайте об этом так: класс model_ имеет свойство DateTime
model_.Date
поэтому нет необходимости проверять год и месяц. Единственная сложная часть - день месяца:
(7 * multiplier) + (7 - dow) + 2
Итак, очень быстрый и эффективный способ проверить это (что лучше, чем бросать и ловить) - использовать метод DateTime.DaysInMonth:
if ((multiplier <= 4) &&
(DateTime.DaysInMonth(model_.Date.Year, model_.Date.Month) <
(7 * multiplier) + (7 - dow) + 2))
{
// error: invalid days for the month/year combo...
}
Еще одно преимущество заключается в том, что вам не нужно создавать экземпляр нового DateTime только для проверки этой информации.
P.S. Обновлен код, чтобы убедиться, что множитель равен <= 4. Это имеет смысл только потому, что любое значение >= 5 завершит тест DaysInMonth...
Посмотрите на метод DateTime.TryParse
РЕДАКТИРОВАТЬ: Woops! DateTime.TryParse не создает исключение изнутри. Я разговаривал с моими ягодицами! В любом случае...
Если скорость важна, вам придется написать свой собственный метод.DateTime.TryParse()
будет вызывать исключение изнутри и приведет к тому, что результат будет идентичен вашему коду в вашем вопросе.
Это может показаться большим количеством кода, но я думаю, что это будет быстрее, если вы ожидаете большой объем ошибок:
public bool GetDate(int year, int month, int day, out DateTime dateTime)
{
if (month > 0 && month <= 12)
{
int daysInMonth = DateTime.DaysInMonth(year, month);
if (day <= daysInMonth)
{
dateTime = new DateTime(year, month, day);
return true;
}
}
dateTime = new DateTime();
return false;
}
Мой вышеприведенный пример не будет обрабатывать все случаи (т.е. я не обрабатываю годы), но он укажет вам в правильном направлении.
Я не знаю быстрее, но
DateTime.TryParse()
Должно сделать то же самое.
Мне было бы интересно, если кто-нибудь скажет мне, если это быстрее (с точки зрения процессорного времени), чем способ, описанный в вопросе.
Одна вещь: Исключения для исключительных случаев. Богоформатированные строки не являются исключительными, но ожидаемыми, поэтому TryParse более уместен.
Использование try/catch для проверки достоверности - это неправильное использование и неправильное представление об исключениях, особенно с уловкой catch-all (последнее уже заставило меня искать часы, почему что-то не работает, и это много раз).
Если механизм синтаксического анализа не работает быстрее, вы можете использовать несколько более подробный метод проверки свойств объекта модели для действительных значений напрямую.