【问题标题】:How can I show a string representation of a nullable DateTime type?如何显示可为空的 DateTime 类型的字符串表示形式?
【发布时间】:2016-02-15 18:32:58
【问题描述】:

用户提供“从”和“到”月份以生成报告(例如,从 1 个月前到 13 个月前;如果他们在 2016 年 2 月 15 日选择此选项,则返回值为 1/1 /2015 年和 2016 年 1 月 1 日)。

我想让用户从“从”或“到”组合框中选择最远或最近的月份。我只想将最远的时间用作“从”,将最接近的时间用作“到”,以避免对他们造成混淆(他们可以做任何他们认为自然的事情)。

所以我从这段代码开始:

int fromMonths = Convert.ToInt32(comboBoxProduceUsageFrom.Text);
DateTime RptParamsNominalFromDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(fromMonths, nextGenerateAndSendDate);
int toMonths = Convert.ToInt32(comboBoxProduceUsageTo.Text);
DateTime RptParamsNominalToDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(toMonths, nextGenerateAndSendDate);

..然后我想将“开始”日期设置为最远的时间,并将“到”日期设置为更近的时间。我第一次尝试这个:

DateTime RptParamsFromDate;
DateTime RptParamsToDate;
if (RptParamsNominalFromDate > RptParamsNominalToDate)
{
    RptParamsFromDate = RptParamsNominalToDate;
    RptParamsToDate = RptParamsNominalFromDate;
}
else if (RptParamsNominalToDate > RptParamsNominalFromDate)
{
    RptParamsFromDate = RptParamsNominalFromDate;
    RptParamsToDate = RptParamsNominalToDate;
}

...但是失败了,“Use of unassigned local variable 'RptParamsFromDate'”(以及“RptParamsToDate”的相同错误)。

所以我尝试给 DateTimes 一个值/非值,如下所示:

DateTime RptParamsFromDate = null;
DateTime RptParamsToDate = null;

...但这给了我,“无法将 null 转换为 'System.DateTime',因为它是不可为空的值类型

所以我再次动了动手指并尝试将 DateTimes 设为空:

DateTime? RptParamsFromDate = null;
DateTime? RptParamsToDate = null;

...但后来我得到,“'System.Nullable' 不包含'ToLongDateString' 的定义,并且找不到接受'System.Nullable' 类型的第一个参数的扩展方法'ToLongDateString' (您是否缺少 using 指令或程序集引用?)"

这是由于这段代码:

RptParamsFromDate.ToLongDateString()

在这个区块中:

MessageBox.Show(string.Format(
    "Using the current configuration, the Produce Usage report would next be sent on {0} and emailed to {1}; the report would cover data from {2} to {3}",
    nextGenerateAndSendDate.ToLongDateString(), 
    emailRecipients,
    RptParamsFromDate.ToLongDateString(),
    RptParamsToDate.ToLongDateString()));

那么我该怎么做才能显示 DateTime 值并仍然安抚脾气暴躁的野兽?

更新

结合来自 SLaks 和 crashmstr 的信息,我最终得到了以下工作方法:

private void buttonTestProdUsageSettings_Click(object sender, EventArgs e)
{
    // Show example of when the report will run, and using which parameters,
    // using the current configuration
    DateTime nextGenerateAndSendDate = GetNextProduceUsageGenerateAndSendDate();
    string emailRecipients = string.Join(",", emailAddresses.ToArray());
    int fromMonths = Convert.ToInt32(comboBoxProduceUsageFrom.Text);
    DateTime RptParamsNominalFromDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(fromMonths, nextGenerateAndSendDate);
    int toMonths = Convert.ToInt32(comboBoxProduceUsageTo.Text);
    DateTime RptParamsNominalToDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(toMonths, nextGenerateAndSendDate);
    if (RptParamsNominalFromDate.Equals(RptParamsNominalToDate))
    {
        MessageBox.Show("The \"from\" and \"to\" values must differ; please try again.");
        return;
    }

    // Allow user to enter either the nearest or furthest value in either the "from" or the "to":
    DateTime? RptParamsFromDate = null;
    DateTime? RptParamsToDate = null;
    if (RptParamsNominalFromDate > RptParamsNominalToDate)
    {
        RptParamsFromDate = RptParamsNominalToDate;
        RptParamsToDate = RptParamsNominalFromDate;
    }
    else if (RptParamsNominalToDate > RptParamsNominalFromDate)
    {
        RptParamsFromDate = RptParamsNominalFromDate;
        RptParamsToDate = RptParamsNominalToDate;
    }

    MessageBox.Show(string.Format(
        "Using the current configuration, the Produce Usage report would next be sent on {0} and emailed to {1}; the report would cover data from {2} to {3}",
        nextGenerateAndSendDate.ToLongDateString(), 
        emailRecipients,
        RptParamsFromDate.HasValue ? RptParamsFromDate.Value.ToLongDateString() : "No \"from\" Date",
        RptParamsToDate.HasValue ? RptParamsToDate.Value.ToLongDateString() : "No \"to\" Date"));
}

【问题讨论】:

  • RptParamsFromDate.HasValue ? RptParamsFromData.Value.ToLongDateString() : "No Date"
  • 这仍然给了我,“'System.Nullable' 不包含'ToLongDateString' 的定义,并且没有扩展方法'ToLongDateString' 接受'System.Nullable 类型的第一个参数' 可以找到(您是否缺少 using 指令或程序集引用?)"
  • 我的错 - 我忘记了“价值”;它适用于: RptParamsFromDate.HasValue ? RptParamsFromDate.Value.ToLongDateString() : "No \"from\" Date",

标签: c# datetime nullable unassigned-variable


【解决方案1】:

您正在尝试使用可空类型的值。

为此,您需要访问其.Value 属性,该属性返回一个常规的DateTime 值。

请注意,如果它实际上为 null,则会引发异常。

【讨论】:

    【解决方案2】:

    要添加到 Slaks 的原始答案,您获得第一个答案的原因是因为您必须尝试在代码后面引用 RptParamsFromDate 或其亲属。问题是因为这个:

    你已经完成了:

    1. 创建变量
    2. 是真的吗?不? ...好的
    3. 还有什么是真的吗?不? ...好的
    4. 变量仍未设置为任何值。 (因为RptParamsNominalFromDate == RptParamsNominalToDate
    5. (假设)您已尝试访问该变量。

    使用未分配的局部变量“RptParamsFromDate””(以及“RptParamsToDate”的相同错误

    将其设置为DateTime? 将在某种程度上超越这一点,但您需要首先研究逻辑问题。确保在稍后尝试使用它之前检查它是否为空。

    【讨论】:

    • RptParamsNominalFromDate 只有在用户为两者选择相同的值时才会等于 RptParamsNominalToDate(到目前为止还没有发生,因为用户是我)。不过,我会添加代码来防止这种可能性/不测性。
    • 正确。但是编译器不知道这一点。 :)
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多