首页 > 解决方案 > 带有表达式的属性中使用的 Nullable DateTime 返回意外的默认值

问题描述

我有以下两个方法扩展:

public static class DateTimeConverter
{
    public static DateTime? Convert(this DateTime? time) =>
        time != null
        ? new DateTime(time.Value.Ticks) :
        default;
}

还有一个:

public static class DateTimeConverterExplicit
{
    public static DateTime? Convert(this DateTime? time) =>
        time != null
        ? new DateTime(time.Value.Ticks) :
        (DateTime ?)default;
}

运行以下代码时:

DateTime? dateTime = default;

var first = DateTimeConverter.Convert(dateTime);
var second = DateTimeConverterExplicit.Convert(dateTime);

Console.WriteLine($"First: {first}");
Console.WriteLine($"Second: {second}");

我得到以下输出:

First: 1-1-0001 00:00:00
Second:

我想知道为什么 C# 认为它应该在使用第一个时返回 DateTime 的默认值DateTimeConverter(而不是 的默认值Nullable<DateTime>)。当我将其显式转换为DateTime?默认值时,正如预期的那样。

当我重写第一个如下:

public static DateTime? Convert(this DateTime? time)
{
    if (time != null)
    {
        return new DateTime(time.Value.Ticks);
    }
    else
    {
        return default;
    }
}

它也可以按预期工作。所以不知何故 C# 无法确定正确的类型。有谁知道为什么会这样?

标签: c#

解决方案


三元表达式中使用的类型的规则是两个子表达式必须是相同的类型,或者其中一个类型必须是另一个的合法目标类型。

在第一种方法中,您的两个子表达式是DateTime, not DateTime?default这里从另一个子表达式中获取DateTime类型,因此成为,它不从目标、return语句以及方法返回类型中获取类型。

相反,三元表达式被评估为 a DateTime,然后这个值被默默地提升为 a DateTime?,但是损坏已经造成了。

在您的最后一个示例中,使用两个return语句,default从方法中获取所需的类型,因为它正在return语句中使用,并变为DateTime?,而在另一个return语句中,该DateTime值再次被默默地提升为DateTime?


推荐阅读