#c# #methods #properties #boolean
#c# #методы #свойства #логическое
Вопрос:
Я пытаюсь создать метод, который проверяет, правильно ли вставлены день, месяц и год. Метод возвращает TRUE, если дата в порядке, и FALSE, если дата НЕ в порядке. Проблема: код всегда возвращает false .
const int max_year = 2100;
const int min_year = 1900;
static bool CheckDate(int d, int m, int y)
{
if (d < 1 || d > 31)
{
if (m < 1 || m > 12)
{
if (y < min_year || y > max_year)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
}
else
{
return true;
}
}
И затем я проверяю дату в свойстве, например:
public int Day
{
get
{
return day;
}
set
{
if (CheckDate(dan, mesec, year) == true)
{
day = value;
}
else
{
throw new Exception("Day is incorrect!");
}
}
}
Комментарии:
1. Помимо вашей реальной проблемы, что, если я скажу ему подтвердить 31 апреля? Есть лучшие способы сделать это, когда вам не нужно создавать собственное решение.
2. Отлично работает с CheckDate(1,1,2019)?
3. Это всего лишь простой пример. Я собираюсь добавить другие проверки позже. На данный момент я проверяю только, находится ли день между 1 и 31, месяц между 1 и 12, год между 1900 и 2100. @BrootsWaymb
4. DateTime уже может это сделать, поэтому нет необходимости переопределять его. Вы могли бы использовать, например
static bool CheckDate(int d, int m, int y) { return min_year <= y amp;amp; y <= max_year amp;amp; DateTime.TryParse($"{y}-{m}-{d}", out _); }
.5. Если вы это сделаете
CheckDate(5, 2000, 123456)
, это вернетсяtrue
, потому что, когда ваш d находится между 1 и 31, вы всегда возвращаете true . То же самое дляCheckDate(0, 5, 2000)
Ответ №1:
Как можно проще, просто преобразуйте свои числа в строку, а затем выполните DateTime .Попробуйте выполнить синтаксический анализ в формате ггггММдд
bool CheckDate(int y, int m, int d)
{
string t = $"{y:D4}{m:D2}{d:D2}";
return DateTime.TryParseExact(t, "yyyyMMdd", CultureInfo.InvariantCulture,DateTimeStyles.None, out DateTime dt);
}
Конечно, если вы хотите ограничить допустимые годы, вы можете добавить простую логику для проверки переменной y, как вы уже делаете сейчас, прежде чем создавать строку для синтаксического анализа.
if (y < min_year || y > max_year)
return false;
....
Комментарии:
1. Вам не нужен цикл создания строки и ее повторного анализа. Вы можете просто попытаться создать a
new DateTime(y, m, d)
, который будет выдавать любую недопустимую дату.2. Нет, это было бы неправильно, потому что вы будете управлять кодом, используя исключения. TryParse позволит избежать дорогостоящего исключения. Это будет намного быстрее с недопустимыми датами.
3. @derpirscher TryParseExact позволяет избежать создания исключения, хотя и вы не хотите специально создавать исключения.
4. С точки зрения производительности, создание исключения обходится дорого. Рекомендуется избегать этого в «обычной» логике проверки. РЕДАКТИРОВАТЬ: 3 похожих комментария одновременно 🙂
5. Вместо того, чтобы возвращать результат TryParseExact , перехватите результат в переменной, подобной этой: var result = DateTime . Попробуйте ParseExact . . . . И если оно равно false, верните его, но если оно true, убедитесь, что дата находится между 1 января 1900 года и 31 декабря 2100 года
Ответ №2:
Я хочу указать на возможную ошибку и / или плохой дизайн в вашем установщике свойств (это может быть причиной того, что ваш «код всегда возвращает false«).
Если вы посмотрите внимательно, вы увидите, что CheckDate
это всегда вызывается с параметрами dan
, mesec
и year
. Как вы знаете, value
значение должно быть установлено ( Day = 1
, или Day = 500
) , но оно не является частью CheckDate
-call .
Если это ваша цель, я могу сказать, что это очень плохой дизайн. Вы должны вызывать CheckDate
прямо в своем коде, а не с помощью почти побочных эффектов, которые выглядят как установщик свойств.
public int Day
{
get
{
return day;
}
set
{
// Why this?
if (CheckDate(dan, mesec, year) == true)
{
day = value;
}
else
{
throw new Exception("Day is incorrect!");
}
}
}
Ответ №3:
Или вы могли бы сделать это :
static bool CheckDate(int d, int m, int y)
{
try
{
// This will throw an exception if the year, month or day are invalid
var temp = new DateTime(y, m, d);
return true;
}
except
{
return false;
}
}