在搜索之后我似乎无法找到为什么C#编译器抱怨局部变量 dteDest 在行中未分配
if (dteSrc == dteDest) {
如果我更换行
,则错误消失DateTime dteSrc, dteDest;
与
DateTime dteSrc, dteDest = DateTime.MinValue;
据我所知,如果dteDest没有被DateTime.TryParse初始化,那么代码将永远不会到达比较行。它是out参数。
我的逻辑是:
void StrangeLogic(object srcData, object currentDataObj) {
DateTime dteSrc, dteDest;
bool booHaveNewDate = DateTime.TryParse(srcData.ToString(), out dteSrc);
bool booHaveOrigDate = (currentDataObj != null)
&& DateTime.TryParse(currentDataObj.ToString(), out dteDest);
if (booHaveNewDate && booHaveOrigDate) {
if (dteSrc == dteDest) {
// Get a "use of unassignned local variable 'dteDest'
// unless dteDest = DateTime.MinValue beforehand
}
}
}
此外,如果我更改行
bool booHaveNewDate = DateTime.TryParse(srcData.ToString(), out dteSrc);
以下
bool booHaveNewDate = (srcData != null) && DateTime.TryParse(srcData.ToString(), out dteSrc);
然后编译器抱怨srcDate也没有被分配。
有没有人能指出我正确的方向我缺少什么 - 我不是指参数检查等我关心为什么编译器逻辑似乎被使用常见的TryParse函数所欺骗?
即使扩展逻辑仍然会产生相同的错误(使用未分配的局部变量)
bool booHaveOrigDate;
if (currentDataObj != null)
booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest);
else
booHaveOrigDate = false;
if (booHaveOrigDate) {
if (dteSrc == dteDest) {
看起来无论编译器如何处理null检查(currentDataObj!= null)都会阻止它正确地确定dteDest,除非已分配
将其更改为此代码并且没有问题(除了空对象上可能的.ToString()之外
bool booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest);
if (booHaveOrigDate) {
if (dteSrc == dteDest) {
答案 0 :(得分:4)
您的替换不正确,应该是:
DateTime dteSrc = DateTime.MinValue, dteDest = DateTime.MinValue;
但是你应该使用TryParse的返回变量,如果你的booHaveNewDate是一个bool来看看tryparse是否有效:
DateTime dteSrc, dteDest;
if(DateTime.TryParse(srcData.ToString(), out dteSrc) && DateTime.TryParse(currentDataObj.ToString(), out dteDest))
{
if (dteSrc == dteDest) {
// Do your stuff here
}
}
现在您不必在开头指定日期。
**您应该在使用前测试此代码,它不是生产代码,可能包含错误
答案 1 :(得分:3)
编译器正式正确,dteDest
(作为out
参数)的赋值是有条件的。在编译器的眼中,它可能不会发生。编译器不“理解”TryParse()后面的逻辑。
以下是类似的情况:
int f(int x)
{
int r;
if (x <= 5) r = 1;
if (x > 5) r = 2;
return r; // error: use of uninitialized var
}
另外,使用
进行初始化似乎更符合逻辑 DateTime dteSrc = default(DateTime), dteDest = default(DateTime);
它是相同的值(DateTime.MinValue)。
答案 2 :(得分:1)
我可能错了,但我不认为编译器在报告此错误时会尝试广泛地剖析您的代码。我目前正试图找到一些来源来支持我的理论。与此同时,我的猜测是这是一个设计决策,因为如果一个人需要超过几秒才能看到一个变量在初始化之前不会被使用,那么可能是一个更好的编码决定,只需将其初始化为null首先是为了避免混淆。
编辑:
好吧,我做了一些环顾四周,虽然我发现了几个人说的基本相同的例子我找不到任何官方文件说明这一点。以下是我发现的回复:
“编译器完全有权不知道你的逻辑。”
http://www.pcreview.co.uk/forums/use-unassigned-local-variable-error-t3067479.html
“......当存在控制流结构时,它无法评估情况,因为它没有执行代码,所以它不知道这些值是否被分配。”
http://bytes.com/topic/c-sharp/answers/917965-why-am-i-getting-unassigned-local-variable-errors
答案 3 :(得分:0)
dteDest
, currentDataObj == null
将没有设置值
如果您将行更改为:
,它将起作用bool booHaveOrigDate = DateTime.TryParse(currentDataObj != null ? currentDataObj.ToString() : string.Empty, out dteDest);
答案 4 :(得分:0)
编译器逻辑似乎被使用常见的TryParse函数所迷惑
上面的问题可以通过以下事实轻松回答:当编译器编译代码时,它不会查看该方法在内部执行的操作,而只是查看签名。它知道它可以返回一个可能为true或false的布尔值,并且它知道它正在设置dteDest
的值。
但这不是你的问题。问题出在以下几行:
bool booHaveOrigDate = (currentDataObj != null)
&& DateTime.TryParse(currentDataObj.ToString(), out dteDest);
使用&&
运算符,如果第一部分为false,则不会评估第二部分。这被称为短路评估,并且理论上如果第一部分是假的那么第二部分是什么并不重要 - 整体结果总是错误的。
因此,在这种情况下,dteDest永远不会被设置,并且编译器认为这是一个问题,即使您查看逻辑并说如果未设置代码将永远不会运行。
简单的事实是人们经常可以发现超出编译器的优化和特殊情况。听起来你已经意识到只需通过检查开头的参数然后返回它的null就可以解决这个问题。