为什么这段代码被认为是"possible 'System.InvalidOperationException'"?

Why is this code considered a "possible 'System.InvalidOperationException'"?

Resharper 建议我更改此代码:

if (getBeginDate)
{
    return (DateTime)RptParamsFromDate;
}

...为此:

if (getBeginDate)
{
    if (RptParamsFromDate != null) return (DateTime)RptParamsFromDate;
}

...因为,“可能 'System.InvalidOperationException'” 但是当我接受建议的更改时,它没有编译,说 "not all code paths return a value"

"if" 块有以下 "else":

else
{
    int daysToAddToToDate = DateTime.DaysInMonth(RptParamsToDate.Value.Year, RptParamsToDate.Value.Month) - 1;
    RptParamsToDate = RptParamsToDate.Value.AddDays(daysToAddToToDate);
    return (DateTime)RptParamsToDate;
}

...所以我不知道为什么它看不到 "else" 以确保返回值。

你得到 "not all code paths return a value" 的原因是因为 if 语句。 如果语句为假,则只有一个 if 语句 return 是一条路径。您需要使 both 语句 return 成为一个值

示例:

if (getBeginDate)
{
    if (RptParamsFromDate != null)
       return (DateTime)RptParamsFromDate;
    else 
    { 
        int daysToAddToToDate = DateTime.DaysInMonth(RptParamsToDate.Value.Year, RptParamsToDate.Value.Month) - 1;
        RptParamsToDate = RptParamsToDate.Value.AddDays(daysToAddToToDate);
        return (DateTime)RptParamsToDate;
    }
}
else { return null; }

好的,您的问题可以通过以下方法重现:

void Main()
{
    DoSomething();
}
DateTime? MaybeGetDate()
{
    return null;
}
DateTime DoSomething()
{
    DateTime? test = MaybeGetDate();
    return (DateTime)test;
}

我不确定 RptParamsFromDate 的类型,但它是 Nullable<DateTime> 或引用类型。换句话说,有关可能的无效操作异常的警告是因为您可能试图将 null 转换为 DateTime,这是不可能的。

现在,Resharper 有点困惑,因为它的默认 'fix' 是简单地检查 null。但是你最终会得到这个:

DateTime DoSomething()
{
    DateTime? test = MaybeGetDate();
    if (test != null)
        return (DateTime)test;
}

这应该清楚它为什么不编译 - 如果 test 为空,该方法不会 return 任何东西。所以在这种情况下你需要手动return一个合适的DateTime。这是 Resharper 不能或不会帮助的事情。在这种情况下,也许 DateTime.MinValue 是合适的人选。

"else" 不会 确保在您的示例中 return 编辑了一个值。

方法体:

if (getBeginDate)
{
    if (RptParamsFromDate != null) return (DateTime) RptParamsFromDate;
}
else
{
    int daysToAddToToDate = DateTime.DaysInMonth(RptParamsToDate.Value.Year, RptParamsToDate.Value.Month) - 1;
    RptParamsToDate = RptParamsToDate.Value.AddDays(daysToAddToToDate);
    return (DateTime)RptParamsToDate;
}
getBeginDate 为真且 RptParamsFromDate 为空时,

将 return 什么都没有。

一个return方法体末尾的默认值可以解决这个问题:

if (getBeginDate)
{
    if (RptParamsFromDate != null) return (DateTime) RptParamsFromDate;
}
else
{
    int daysToAddToToDate = DateTime.DaysInMonth(RptParamsToDate.Value.Year, RptParamsToDate.Value.Month) - 1;
    RptParamsToDate = RptParamsToDate.Value.AddDays(daysToAddToToDate);
    return (DateTime)RptParamsToDate;
}

DateTime defaultValue = DateTime.MinValue;//or what have you
return defaultValue;