我真的想要回复最短的约会吗?

时间:2012-06-08 16:15:19

标签: c# datetime resharper default-value

一位老同事曾经引用他的父亲谈论工具,“你必须比它聪明。”

在下面的代码中,Resharper告诉我,“分配的值不会在任何执行路径中使用”(指向第一行)。如果我接受其提供的帮助,则不会为dt分配值(“今天”)。

这是“我必须比它更聪明”并忽略他们的警告的情况,或者这是一个工具比我聪明的情况,我只是不理解它?

我对这种情况的看法是,如果if语句失败,则返回当前日期(我想要的默认值),但如果我默认Resharper的“需求”,它将返回Datetime的默认值,即最小日期,我假设是7/4/1776或1/1/0000左右。

DateTime dt = DateTime.Now;
if (!(DateTime.TryParse(substr, out dt))) {
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
        if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
            dt = dtpDlgForm.ReturnVal;
        } 
    }
}
return dt;

7 个答案:

答案 0 :(得分:53)

您接受的答案显示了应该正在做什么,但没有解释为什么 Resharper首先抱怨。由于这种解释对于发现问题的其他人有用,因此它是:

遵循Resharper的建议并将第一行更改为:

DateTime dt;

这声明变量dt但不为其分配任何值。这里不需要分配值,因为out keyword会在下一行明确分配值。来自文档:

  

虽然作为out参数传递的变量在传递之前不必初始化,但在方法返回之前需要调用方法来指定值。

强调我的。分配值DateTime.Now是不必要的并且具有误导性,因为永远不会使用该值。

  

我对这种情况的看法是,如果if语句失败,则返回当前日期

这不是你的代码所做的。来自documentation

  

结果:当此方法返回时,包含等效于s中包含的日期和时间的DateTime值,如果转换成功,则转换失败时包含或MinValue。

如果解析失败,则使用您发布的代码,dt将包含值DateTime.MinValue,而不包含您指定的值DateTime.Now

答案 1 :(得分:23)

您的预期逻辑允许三个可能的DateTime返回值(按优先顺序排列):

  1. substr
  2. 的已解析值
  3. 从对话框中选择的值。
  4. 当前日期和时间。
  5. 您可以通过在条件成功时执行单独的return语句来实现此逻辑:

    DateTime dt;
    if (DateTime.TryParse(substr, out dt))
        return dt;
    
    using (var dtpDlgForm = new ReturnDate(
        "Please select the Date that the file was created:")) 
    {
        if (dtpDlgForm.ShowDialog() == DialogResult.OK)
            return dtpDlgForm.ReturnVal;
    }
    
    return DateTime.Now;
    

    修改:有关为何不将值分配给将用作out参数的变量的说明,请参阅Mark Byers’s answer

答案 2 :(得分:20)

这是因为你要为dt赋值,然后将其作为out param传递。如果变量作为out参数传入:

  • 在使用该函数之前必须为其分配一个值
  • 必须在该函数返回之前为其分配值

在您的情况下,您可以通过将第一行更改为:

来修复来自ReSharper消息的消息
DateTime dt;
  

我对这种情况的看法是,如果if语句失败,那么   返回当前日期

事实并非如此。无论您传入的DateTime对象的值如何,它都将始终返回DateTime.MinValue

来自MSDN - DateTime.TryParse(string, out DateTime)

  

结果

     

输入:System.DateTime%

     

当此方法返回时,[result]包含 DateTime值   相当于s中包含的日期和时间,如果转换   成功,或 MinValue如果转换失败。转换   如果s参数为null,为空字符串(“”)或不是,则失败   包含日期和时间的有效字符串表示形式。这个   参数未经初始化传递。

(强调补充)

答案 3 :(得分:8)

out参数始终为其分配值。始终保证被调用函数在返回之前为其赋值。因此,它将覆盖最初分配的值。

答案 4 :(得分:7)

这里的要点是关于使用out parameter modifier

  

虽然作为out参数传递的变量在传递之前不必初始化,但是在方法返回之前需要调用方法来赋值。

无论如何,

DateTime.TryParse会将默认值分配给dt,如果无法解析substr,则生成的dt将具有最短日期时间的值。

答案 5 :(得分:3)

DateTime.TryParse(substr, out dt);

可以返回false,但仍会修改dt。它将尝试尽最大努力完成dt,尽可能地初始化一些值。在c#中使用out修饰符时,您告诉程序初始化它,并且您不应该期望保留传入的值。

你能做的是

DateTime dt;
if (!(DateTime.TryParse(substr, out dt))) {
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
        if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
            dt = dtpDlgForm.ReturnVal;
        } 
        else {
            dt = DateTime.Now;
        }
    }
}

return dt;

答案 6 :(得分:3)

此代码会使警告消失。但我认为道格拉斯的回答更容易阅读。

DateTime dt;
if (!(DateTime.TryParse(substr, out dt))) {
    dt = DateTime.Now;
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
        if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
            dt = dtpDlgForm.ReturnVal;
        } 
    }
}
return dt;