【问题标题】:Nullable DateTime extension throws 'does not contain a definition' exceptionNullable DateTime 扩展抛出“不包含定义”异常
【发布时间】:2021-08-11 14:33:41
【问题描述】:

在下面的代码中:

void Main()
{
    DateTime cleanDate = DateTime.Now.ToCleanDateTime();    
    DateTime? nullableCleanDate = DateTime.Now;
    nullableCleanDate = nullableCleanDate.ToCleanDateTime();

    cleanDate.Dump();
    nullableCleanDate.Dump();
}

public static class Extensions
{
    //public static DateTime ToCleanDateTime(this DateTime dt)
    //{
    //  dt = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, 0);
    //  return dt;
    //}

    public static DateTime? ToCleanDateTime(this DateTime? dt)
    {
        if (dt.HasValue)
            dt = new DateTime(dt.Value.Year, dt.Value.Month, dt.Value.Day, 0, 0, 0, 0);
        return dt;
    }
}

这一行DateTime cleanDate = DateTime.Now.ToCleanDateTime(); 抛出以下异常。

“System.DateTime”不包含“ToCleanDateTime”的定义 和最好的扩展方法重载 'Extensions.ToCleanDateTime(System.DateTime?)' 有一些无效 论据

如果我在 DateTime public static DateTime ToCleanDateTime(this DateTime dt) 的扩展方法中发表评论,则不会引发错误。

谁能启发我:

  1. 为什么会抛出这个错误(除了明显的错误)?
  2. 有没有办法将这两个扩展组合成一个方法?

我以某种方式期望public static DateTime? ToCleanDateTime(this DateTime? dt) 能够同时处理DateTimeDateTime?

【问题讨论】:

  • 正如您的回答所说,DateTime != DateTime? 因为DateTime? 被编译器转换为Nullable<DateTime>。它是一种完全不同的类型。

标签: c# datetime nullable


【解决方案1】:

这不是抛出的异常,而是编译器错误。前者发生在运行时,后者发生在编译时。这是一个重要的区别。

您收到此错误是因为编译器找不到接受DateTime 的扩展方法,只有一个带有DateTime? 的扩展方法。这些是完全不同的类型。 Nullable<T>T 没有任何继承关系,因此您不能让 Nullable<T> 的重载接受 T,反之亦然。

您可以通过让一个调用另一个来组合这些方法:

public static class Extensions
{
    public static DateTime ToCleanDateTime(this DateTime dt)
    {
      return new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, 0);      
    }

    public static DateTime? ToCleanDateTime(this DateTime? dt)
    {
        if (dt.HasValue)
        {
            return dt.Value.ToCleanDateTime();
        }
        return dt;
    }
}

或者您可以只使用DateTime.Date,它返回与您的扩展方法相同并保留Kind,而不是上面的代码Kind will be Unspecified,不管输入是Kind

【讨论】:

    【解决方案2】:

    如果 dt 的数据类型为 DateTime?,您可以使用 dt.value.Month 和 dt.Value.Year 等来获取数据

    【讨论】:

    • 这没有回答问题。
    猜你喜欢
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 2011-05-30
    • 2019-04-21
    • 2018-05-11
    相关资源
    最近更新 更多