Я написал эту логику, чтобы сравнить исходный год / месяц с ответным годом / месяцем. но я хочу написать это лучше. если исходный год / месяц больше или равен ответному году / месяцу, тогда пройти. любое предложение??

if (source?.Year == response?.Year)
{
    return source?.Month >= response?.Month
        ? Outcome.Pass()
        : Outcome.Fail();
}
else if (source?.Year < response?.Year)
{
    return Outcome.Fail();
}
else if (source?.Year > response?.Year)
{
    return Outcome.Pass();
}
else
{
    return Outcome.Fail();
}
c#
2
Rani 17 Апр 2020 в 18:42

2 ответа

Лучший ответ

Вам просто нужно сравнить source с началом месяца response.

var responseMonthBegin = response.HasValue 
    ? new DateTime(response.Value.Year, response.Value.Month, 1)
    : (DateTime?)null;

return source >= responseMonthBegin ? Outcome.Pass() : OutCome.Fail();
4
juharr 17 Апр 2020 в 15:56

Просто обрежьте каждый до начала месяца:

private static DateTime TruncateToMonth(DateTime date) =>
    new DateTime(date.Year, date.Month, 1, 0, 0, 0);

Тогда вы можете использовать:

// TODO: Null handling
return TruncateToMonth(source) >= TruncateToMonth(response)
    ? Outcome.Pass()
    : Outcome.Fail();

Обратите внимание на TODO - я вообще не пытался обрабатывать нулевые значения. Я никогда не могу вспомнить правила достаточно четко, чтобы предсказать, что будет делать ваш текущий код. Если я не могу понять это, не концентрируясь, шансы на то же самое будут относиться к любому, кто пытается прочитать код тоже :) Так что я бы сделал действительно ясным, как вы хотите обрабатывать пустые значения, например.

return source == null || response == null ? Outcome.Fail()
    : TruncateToMonth(source.Value) >= TruncateToMonth(response.Value) ? Outcome.Pass()
    : Outcome.Fail();

Как отмечено в комментариях, вам не нужно усекать исходное значение - я просто нахожу более понятным, если вы это сделаете.

3
Jon Skeet 17 Апр 2020 в 16:43