C# 错误 CS0165:使用未分配的局部变量 - 忽略逻辑和输出引用
环顾四周后,我似乎无法找到为什么 C# 编译器抱怨行中的局部变量 dteDest 未分配
if (dteSrc == dteDest) {
错误就会消失
DateTime dteSrc, dteDest;
如果我将行替换为 ,
DateTime dteSrc, dteDest = DateTime.MinValue;
据我所知,代码将如果 dteDest 未由 DateTime.TryParse 初始化(它是其输出参数),则永远不会到达比较线。
我的逻辑是:
- 如果 currentDataObj 为 null,则 booHaveOrigDate 为 false,第一个 if 失败
- 如果 currentDataObj 不为 null 但无法转换为 DateTime,则 booHaveOrigDate 为 false,第一个 if > 失败
- DateTime.TryParse 如果无法将其与 && 一起转换为 DateTime,则返回 false意味着 dteDest 将永远不会被使用。
简单示例代码
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) {
看来编译器对空检查(currentDataObj!= null)所做的任何事情都会阻止它正确确定 dteDest 不会被访问,除非分配
将其更改为此代码,没有问题(除了空对象上可能的 .ToString()
bool booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest);
if (booHaveOrigDate) {
if (dteSrc == dteDest) {
After searching around I cant seem to locate why the C# compiler is complaining that the local variable dteDest is unassigned in the line
if (dteSrc == dteDest) {
The error goes away if I replace the line
DateTime dteSrc, dteDest;
with
DateTime dteSrc, dteDest = DateTime.MinValue;
As far as I can see the code will never reach the comparison line if dteDest is not initialised by the DateTime.TryParse which it is an out parameter for.
My logic is:
- If currentDataObj is null then booHaveOrigDate is false and the first if fails
- If currentDataObj is not null but cant be converted to a DateTime then booHaveOrigDate is false and the first if fails
- DateTime.TryParse will return false if it cant convert to a DateTime this along with the && means that dteDest will never be used.
Simple Sample Code
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
}
}
}
Also if I change the line
bool booHaveNewDate = DateTime.TryParse(srcData.ToString(), out dteSrc);
to the following
bool booHaveNewDate = (srcData != null) && DateTime.TryParse(srcData.ToString(), out dteSrc);
then the compiler complains that srcDate is not assigned as well.
Could anyone point me in the right direction to what I am missing - I dont mean about parameter checking etc I am concerned with why the compiler logic seems to be fooled by the use of a common TryParse function?
Additional Info
Even expanding out the logic still gives the same error (use of unassigned local variable)
bool booHaveOrigDate;
if (currentDataObj != null)
booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest);
else
booHaveOrigDate = false;
if (booHaveOrigDate) {
if (dteSrc == dteDest) {
It appears that it is whatever the compiler does with the null checking (currentDataObj != null) that prevents it from correctly determing the dteDest wont be accessed unless assigned
Change it to this code and no problems (aside from the possible .ToString() on a null object
bool booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest);
if (booHaveOrigDate) {
if (dteSrc == dteDest) {
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的替换不正确,应该是:
但是您应该使用 TryParse 的返回变量,它是一个 bool 来查看 tryparse 是否有效,而不是如果您的 booHaveNewDate:
现在您不必在开始时分配日期。
** 您应该在使用之前测试此代码,它不是生产代码并且可能包含错误
Your replace is incorrect, it should be:
However you should use the return variable of TryParse, which is a bool to see if tryparse worked instead if your booHaveNewDate:
Now you do not have to assign the dates in the beginning.
** You should test this code before using, it is no production code and can contain errors
编译器在形式上是正确的,对
dteDest
的赋值(作为out
参数)是有条件的。在编译器看来,这可能不会发生。编译器不“理解”TryParse() 所遵循的逻辑。这是一个类似的情况:
顺便说一句,用
相同的值(DateTime.MinValue)进行初始化似乎更符合逻辑。
The compiler is formally correct, the assignment to
dteDest
(asout
parameter) is conditional. In the eyes of the compiler it might not happen. The compiler doesn't 'understand' the logic that follows from TryParse().Here is a similar situation:
On a side note, it seems slightly more logical to initialize with
it is the same value (DateTime.MinValue) though.
我可能是错的,但我不认为编译器在报告此错误时会尝试广泛剖析您的代码。我目前正在尝试寻找一些来源来支持我的理论。同时,我的猜测是,这是一个设计决策,因为如果一个人需要花费超过几秒钟的时间才能看到变量在初始化之前不会被使用,那么将其初始化为 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
I could be wrong but I don't think the compiler attempts to dissect your code that extensively when reporting this error. I'm currently trying to find some source to back up my theory. In the mean time, my guess would be that this is a design decision because if it takes a person more than a couple seconds to see that a variable will not be used before being initialized it's probably a better coding decision to just null initialize it to begin with in order to avoid confusion.
EDIT:
Well I did a bit of looking around and while I found a couple examples of people saying essentially the same thing I am I cannot find any official documentation stating this. Here are the responses I found though:
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
如果
currentDataObj == null
,dteDest
将不会设置值,如果您将行更改为:
dteDest
will not have a value set ifcurrentDataObj == null
It will work if you change your line to:
编译器逻辑似乎被通用 TryParse 函数的使用所愚弄
上面的问题可以通过以下事实最容易回答:当编译器编译代码时,它不会查看该方法是什么在内部执行时,它只查看签名。它知道它可以返回一个可能为 true 或 false 的布尔值,并且它知道它正在设置 dteDest 的值。
但这并不是你真正的问题。问题在于以下行:
使用
&&
运算符,如果第一部分为 false,则不会计算第二部分。这称为短路评估,其工作原理是:如果第一部分是错误的,那么第二部分是什么并不重要 - 总体结果将始终是错误的。因此,在这种情况下,dteDest 永远不会被设置,并且编译器认为这是一个问题,即使您查看逻辑并说如果未设置,代码将永远不会运行。
简单的事实是,人们经常可以发现编译器之外的优化和特殊情况。你听起来好像你已经意识到你可以简单地通过检查开头的参数然后返回它的空值来解决这个问题。
compiler logic seems to be fooled by the use of a common TryParse function
The question above can be most easily answered by the fact that when the compiler is compiling your code it doesn't look at what that method is doing internally, it just looks at the signature. It knows it can return a boolean that may be true or false and it knows that it is setting the value of
dteDest
.This isn't really your problem though. The problem comes in that the following line:
Uses the
&&
operator which will not evaluate the second part if the first part is false. This is called short circuit evaluation and works on the theory that if the first part is false then it doesn't matter what the second part is - the overall result will always be false.So in this case dteDest is never being set and the compiler feels this is a problem, even if you look at the logic and say that the code will never run if it is not set.
The simple fact is that people can often spot optimisation and special cases that are beyond the compiler. You sound like you are already aware that you can solve this simply just by checking the parameter at the beginning and then returning if its null.