使用带有TryParse的if语句中的“使用未分配的局部变量”

我刚刚在VS2015 .Net v4.5.2控制台应用程序中键入以下代码:

dynamic fromString = "blah", toString = "blah2"; DateTime fromDate, toDate; if (DateTime.TryParse(fromString.ToString(), out fromDate) && DateTime.TryParse(toString.ToString(), out toDate)) { Console.WriteLine(fromDate); Console.WriteLine(toDate); } 

出乎意料的是,我收到错误“使用未分配的局部变量toDate”。 我没想到它,因为只有在’toDate’被赋予第二个TryParse的值时才输入if语句。

不用说,可以通过为’toDate’赋值来解决它:

 DateTime fromDate, toDate = DateTime.MinValue; 

或者将&&更改为&,以便无论第一次失败都执行两个TryPars。

但是,我想知道为什么会出现错误? 如果fromString和toString变量是字符串,则不会发生错误,并且编译器不会给出toDate未分配的错误。 因此我想知道为什么编译器对stringdynamic.ToString()不同?

这是罗斯林的一个重大变化,记录在这里 :

先前编译器为动态表达式实现的明确赋值规则允许某些代码可能导致读取的变量未明确赋值。 有关此报告,请参阅https://github.com/dotnet/roslyn/issues/4509 。

[剪辑说明示例]

由于这种可能性,如果val没有初始值,编译器不得允许编译该程序。 先前版本的编译器(在VS2015之前)允许该程序编译,即使val没有初始值。 罗斯林现在诊断这种尝试读取可能未初始化的变量。

这是因为你使用短路运算符&&,这意味着如果第一个TryParse返回false,则永远不会执行第二个TryParse,从而使ToDate变量保持未分配状态。

试试吧,用&替换&&,你的错误就会消失,因为现在总是会执行两个TryParse调用。

编译器不够聪明(它不分析你的逻辑)知道在某些情况下内部代码不会被执行。

编辑:@Simon,我重新阅读了你的问题,发现你已经知道了……也许是因为.ToString总是存在于一个对象上,但并不总是存在于动态上(例如当它是一个com对象时),并且在这种情况下,编译器执行较少的检查?