我刚刚在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"。我没有预料到它,因为if语句只有在' toDate'从第二个TryParse分配一个值。
毋庸置疑,可以通过分配“日期”来解决这个问题。一个值:
DateTime fromDate, toDate = DateTime.MinValue;
或更改&&到&这样无论第一次失败都会执行两个TryPars。
但是,我想知道为什么会出现错误?如果fromString和toString变量是字符串,则不会发生错误,并且编译器不会给出toDate未分配的错误。因此,我想知道为什么编译器会以不同的方式处理string
和dynamic.ToString()
?
答案 0 :(得分:3)
这是因为你使用了短路算子&&,这意味着如果第一个TryParse返回false,则永远不会执行第二个TryParse,从而使ToDate变量保持未分配状态。
尝试一下,替换&&由&并且您的错误将消失,因为现在将始终执行所有TryParse调用。
编译器不够聪明(它不会分析你的逻辑)知道在某些情况下内部代码不会被执行。
编辑:@Simon,我重新阅读了你的问题,发现你已经知道了......也许是因为.ToString总是存在于一个对象上,但并不总是存在于一个动态上(例如当它是一个com对象时) ),在这种情况下编译器执行较少的检查?答案 1 :(得分:1)
这是Roslyn的一个重大变化,记录为here:
以前的编译器为动态表达式实现的明确赋值规则允许某些代码可能导致读取的变量未明确赋值。有关此问题的报告,请参阅https://github.com/dotnet/roslyn/issues/4509。
[snip说明示例]
由于这种可能性,如果val没有初始值,编译器不得允许编译该程序。先前版本的编译器(在VS2015之前)允许该程序编译,即使val没有初始值。罗斯林现在诊断出这种尝试读取可能未初始化的变量。