简体   繁体   English

带有表达式的属性中使用的 Nullable DateTime 返回意外的默认值

[英]Nullable DateTime used in property with expression returns unexpected default value

I have the following two method extensions:我有以下两个方法扩展:

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

And the other one:还有一个:

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

When running the following code:运行以下代码时:

DateTime? dateTime = default;

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

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

I get the following output:我得到以下 output:

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

I wonder why C# thinks it should return the default value of DateTime when using the first DateTimeConverter (and not the default value of Nullable<DateTime> ).我想知道为什么 C# 认为它应该在使用第一个DateTimeConverter时返回 DateTime 的默认值(而不是Nullable<DateTime>的默认值)。 When I explicit cast it to a DateTime?当我明确将其转换为DateTime? the default value is as expected.默认值符合预期。

When I re-write the first one as follows:当我重写第一个如下:

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

It also works as expected.它也可以按预期工作。 So somehow C# is not able to determine the right type.所以不知何故 C# 无法确定正确的类型。 Does anyone knows why this is happening?有谁知道为什么会这样?

The rule for types used in ternary expression is that both sub-expressions must be the same type, OR one of the types must be a legal target type of the other.三元表达式中使用的类型的规则是两个子表达式必须是相同的类型,或者其中一个类型必须是另一个的合法目标类型。

In the first method, your two sub-expressions are DateTime , not DateTime?在第一种方法中,您的两个子表达式是DateTime ,而不是DateTime? . . default here picks up the type from the other sub-expression and thus becomes DateTime , it does not pick up the type from the target, the return statement and thus the method return type.这里的default从另一个子表达式中获取类型,因此变为DateTime ,它不从目标、 return语句以及方法返回类型中获取类型。

Instead, the ternary expression is evaluated, to a DateTime , and then this value is silently promoted to a DateTime?相反,三元表达式被评估为DateTime ,然后这个值被默默地提升为DateTime? , but then the damage has already been done. ,但是伤害已经造成了。

In your last example, with two return statements, default picks up the required type from the method since it is being used in a return statement, and becomes DateTime?在您的最后一个示例中,使用两个return语句, default从方法中获取所需的类型,因为它在return语句中使用,并变为DateTime? , whereas in the other return statement, the DateTime value is again silently promoted to DateTime? ,而在另一个return语句中, DateTime值再次被默默地提升为DateTime? . .

In addition to Lasse's answer I just wanted to share you how you could have looked it up yourself in Visual Studio.除了 Lasse 的回答之外,我只想与您分享如何在 Visual Studio 中自己查找它。

In your first example you could write default(DateTime) instead of only default and than notice that Visual Studio will tell you that the DateTime can be omiited and you should only write default .在您的第一个示例中,您可以编写default(DateTime)而不是仅default并且注意 Visual Studio 会告诉您可以省略DateTime并且您应该只编写default

在此处输入图像描述

but when you write default(DateTime?) Visual Studio will not produce an hint.但是当你写default(DateTime?) Visual Studio 不会产生提示。

在此处输入图像描述

This tells you that only writing default produces a DateTime object and not DateTime?这告诉您,仅写入default会生成DateTime object 而不是DateTime? . .

Or you could have simply mouse overed default keyword and it would provide a tooltip that tells what it represents a System.DateTime , and not a System.Nullable<T> where T is DateTime .或者您可以简单地将鼠标悬停在default关键字上,它会提供一个工具提示,告诉它代表什么System.DateTime ,而不是System.Nullable<T> ,其中TDateTime

在此处输入图像描述

And now that you know that default results in a DateTime it should be obvious, IMHO, why it displays the MinValue instead of null .现在您知道default结果是DateTime应该很明显,恕我直言,为什么它显示MinValue而不是null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM