2013-06-18 46 views
6

我有一个类定义了以下方法:局部变量(INT)可能无法访问之前被初始化

public bool LogOff(string sessionId) 
{ 
    int res; 
    // Some non related code here.. 
    if (res == 1) 
    { 
     return true; 
    } 
    return false; 
} 

有什么奇怪的是,我看到了“局部变量可能不是之前被初始化访问“错误从Visual Studio(我有ReSharper安装)的IF子句。为什么当“res”是一个值类型,并且应该默认为0?我应该指出,如果我特别将res的值设置为0,那么一切正常。

我在这里错过了什么?我想这些都是编程的基础知识,但显然我不熟悉的基础知识...

+0

错误告诉你你需要做什么你需要做'int res = 0'将它初始化为一个值 – MethodMan

+0

@nvoigt它不是重复的,因为这个例子处理引用类型DateTime,而这个问题是关于值类型的但好的... – Marko

+0

@Marko值和引用类型都有默认值。当它们没有明确设置时,它们都会发出这个错误。对于这篇文章,值和引用类型没有区别。接受的答案也没有提到这种情况下的任何差异。因此,对我来说这是重复的。 – nvoigt

回答

8

“为什么C#以这种方式工作”的答案总是“因为这就是规范中的内容”。 C#语言规范的第5.3.2列出了最初未分配的变量:

  • Instance variables of initially unassigned struct variables.
  • Output parameters, including the this variable of struct instance constructors.
  • Local variables, except those declared in a catch clause or a foreach statement.

至于为什么这是一个错误,第5节。3个状态

A variable must be definitely assigned at each location where its value is obtained.

如果初始化该值为int res = new int();,您将得到默认值零。其他答案中提到了更常见的方法,即将其设置为零。依赖于默认值只会使代码变得不可读,而没有真正的优势。

+0

这是我正在寻找的答案...谢谢! – Marko

+1

@Marko很高兴帮助。语言规范经常被忽视为一种资源,但当你遇到这些类型的问题时,它实际上是非常可读和有用的。你甚至可以购买一个注释的副本进一步澄清。 –

8

Why is this the case when "res" is a value type and as such should default to 0?

即使默认值为0成员字段,当地人需要明确设置的值。编译器会警告你,你正在使用它而不初始化它,因为这可能是一个错误。

虽然从逻辑的角度来看,从技术角度来看,这种“技术上”可能没有问题,但从现实世界的角度来看,您在检查之前从未设置过的值是1)无用的if永远不会是真的)或2)一个错误(你的意思是设置值,但有些改变)。

无论哪种情况,都会发出警告以帮助您防止任何一种情况发生。

I should point out that if I specifically set the value of res to 0 then it's all OK.

当你这样做时,你特别提供了一个值,所以编译器不再警告你。

+0

这不是一个警告,我无法构建解决方案。我得到这个错误:使用未分配的局部变量'res'...这是什么让我感到困惑... – Marko

+1

@Marko Locals!= fields - 在使用它们之前,你必须初始化一个局部变量。编译器将此视为错误而不是“仅处理它”,因为它是真正错误的常见来源。 –

+1

@Marko我认为混淆是因为类型成员的行为不同。在一个类型(即:一个字段)中,一个值类型被初始化为零。方法中的本地成员不一定具有这种行为 - 语言要求您为其分配一些价值。 –

1

问题是未初始化的值不能被C#保证为0。根据language specification,可能不会使用未初始化的变量,因为C#旨在防止您执行明显不好的事情。

其他语言(特别是C和C++)允许这样做的主要原因是因为它是编译器编写器检测并标记此条件的额外工作。

编辑:Here是C#语言规范的相关部分:

+0

你是什么意思,它不能保证?如果它是一种价值类型,怎么可能不成?当我自己没有指定默认值时,声明int的值是多少? – Marko

+1

这取决于如何实施CLR。如果它没有明确地将该内存清零,那么该值将是上次存储在保存变量的内存中的物理位置的内容。 –

+0

所以那里有某种价值?这个值可以为空吗?我仍然不明白为什么不让我建立,如果价值将是什么,即使它是12345 ... – Marko

2

C#要求所有的变量在使用前进行初始化。对于像这样的局部变量,你需要明确地初始化它们。结构或类中的字段不需要显式初始化,因为它们接收其默认值作为对象构造的一部分。

所以在这里,你只需要做

int res = 0; 

和一切都会好的。

0

默认初始化适用于类/结构成员,这里不适用,因为res是局部变量;作为变量,而不是数据成员,“使用前需要初始化”适用。