【问题标题】:C# use of unassigned variableC#使用未赋值的变量
【发布时间】:2015-11-27 08:07:03
【问题描述】:

我有以下 C# 设置:

DateTime DOB;
DateTime.TryParse(dicGuarantor["DateOfBirth"].ToString(), out DOB);
....
DateOfBirth = DOB;

我的问题与TryParse 失败的情况有关。

据我了解,变量

DateTime DOB

将保持未分配状态,这意味着在这种情况下,当代码到达该行时:

DateOfBirth = DOB;

它会给出与使用未分配变量有关的错误。

但是,这在我的代码中似乎没有发生,没有发生错误并且页面按预期显示。

我担心这里确实存在错误,但我没有看到它,并且代码会因此而中断。

谁能澄清一下 - 网上似乎没有多少可以回答这个问题。

作为说明,我试过了:

DateTime DOB = null;

在声明中,但上面写着:

'无法将 null 转换为 'System.DateTime',因为它是 非空值类型'

编辑:

鉴于下面的答案,我将首先将变量DateOfBirth的声明添加到问题中:

public DateTime? DateOfBirth { get; set; }

这意味着这是nullable DateTime Obeject

现在,假设 TryParse 失败,它将分配的变量:

DOB = DateTime.MinValue;

因此:

DateOfBirth = DateTime.MinValue;

现在在代码的其他地方,

我有以下几点:

if (DateOfBirth.HasValue)
...

从运行代码来看,当DateOfBirth 被赋值为DateTime.MinValue 时,这似乎会返回false

这符合预期吗?

【问题讨论】:

  • 不能设置DOB=null,如果需要,需要声明为nullable
  • dicGuarantor["DateOfBirth"]中存储的值的类型是什么?如果它已经是 DateTime,只需转换:DOB = (DateTime)dicGuarantor["DateOfBirth"];

标签: c#


【解决方案1】:

out参数必须通过方法赋值,不管返回什么,所以TryParse会在返回false之前给value赋值。引用 C# 规范:

在方法中,就像局部变量一样,输出参数最初被认为是未分配的,并且必须在使用其值之前明确分配。

方法的每个输出参数必须在方法返回之前明确分配。

如果你查看source,它会在做任何其他事情之前分配给DateTime.MinValue

internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out DateTime result) {
    result = DateTime.MinValue;
    DateTimeResult resultData = new DateTimeResult();       // The buffer to store the parsing result.
    resultData.Init();
    if (TryParse(s, dtfi, styles, ref resultData)) {
        result = resultData.parsedDate;
        return true;
    }
    return false;
}

【讨论】:

  • HasValue 在这种情况下将返回 trueMinValue 是一个值。没有TryParse 重载需要Nullable<DateTime>
  • 确认,如果变量的值为 DateTime.Minvalue,你会期望它为语句 if (DateOfBirth.HasValue) 返回 false
  • 不,它会返回true。对不起,误解了你的评论。更新了我的以反映这一点。
【解决方案2】:

不,当您调用带有“out”参数的方法时,该方法必须为其分配一个值:

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

Source

你甚至不能编译这个:

public void Foo(out DateTime value)
{
}

CS0177 必须在控制之前分配输出参数“值” 离开当前方法

【讨论】:

    【解决方案3】:

    docs of this method。它说当 TryParse 失败时,它会将 DateTime.MinValue 分配给您的 out 变量,因此您不能指望在调用 TryParse 方法后将其取消分配。它将包含一些价值。值是否有效取决于TryParse 的返回结果。如果它返回 true,则 out 参数将转换日期,否则,它将以 DateTime.MinValue 作为其值。

    【讨论】:

      【解决方案4】:

      也许试试这个:

      if(!DateTime.TryParse(dicGuarantor["DateOfBirth"].ToString(), out DOB))
      {
          DOB = new DateTime()
      }
      

      如果在尝试解析时失败,则生成新的 DateTime 对象,该对象将为空

      或者使用 DateTime 作为可以为空的DataTime?

      【讨论】:

      • 不需要这样做,DOB总是明确分配的(这是使用“out”的要求)
      • 是的,但是如果皮重失败,这允许做任何我们想做的事情,这次我使用新对象初始化作为示例
      猜你喜欢
      • 2014-04-22
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      相关资源
      最近更新 更多