c# - 在带有表达式的属性中使用的可空 DateTime 返回意外的默认值

标签 c#

我有以下两个方法扩展:

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# 在使用第一个 DateTimeConverter 时认为它应该返回 DateTime 的默认值(而不是 Nullable<DateTime> 的默认值)。当我将它显式转换为 DateTime? 时默认值符合预期。

当我重写第一个如下:

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

它也按预期工作。所以 C# 无法以某种方式确定正确的类型。有谁知道为什么会这样?

最佳答案

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

在第一种方法中,您的两个子表达式是DateTime,而不是DateTime?default 这里 picks up 来自其他子表达式的类型,因此变成 DateTime,它不从目标中选择类型, return 语句和方法返回类型。

取而代之的是,三元表达式被评估为 DateTime,然后这个值被默默地提升为 DateTime?,但损害已经造成。

在你的最后一个例子中,有两个 return 语句,default 从方法中获取所需的类型,因为它被用于 return 语句,并变为 DateTime?,而在另一个 return 语句中,DateTime 值再次被静默提升为 DateTime?.

关于c# - 在带有表达式的属性中使用的可空 DateTime 返回意外的默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61748464/

相关文章:

c# - 使用通用集合装箱和拆箱

c# - 后台工作人员重用错误 C#

c# - 从任务管理器启动进程并隐藏命令行参数

c# - Sendgrid 退订首选项

c# - 如何实现从非托管 DLL 到 .net 应用程序的回调接口(interface)?

c# - 使用 protobuf-net 生成 C# 时保留 proto 注释

c# - 显示名称为 'VJSharpCodeProvider' 的程序集加载失败

c# - 将图表坐标转换为像素

c# - 需要有关 C# LINQ 列表聚合表达式的建议

c# - 如何使用 FluentAssertions 测试嵌套集合