2012-09-03 160 views
0

我只是想知道为什么编译器会给我这个错误。每次调用函数时都会执行try块,这意味着该变量将被分配。但它仍然不让我编译。使用未分配的本地变量错误的原因

using System; 

namespace Checking 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int intNum; 
      intNum = readValue("Please enter a number: "); 

     } 
     static int readValue(string strPrompt) 
     { 
      int intRes; 
      Console.WriteLine(strPrompt); 
      try 
      { 
       intRes = Convert.ToInt32(Console.ReadLine()); // Gets assigned here! But still doesnt allow me to compile! 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Please enter a numeric value.\n"); 
       readValue(strPrompt); 
      } 
      return intRes;  
     } 
    } 
} 

把回报intRes try块内可以让我摆脱错误的,但随后的错误影响了说不是所有的代码路径返回一个值。我理解错误,但我仍然不明白为什么它不允许我编译,try块每次都被执行正确吗?

我也知道给intRes指定0会摆脱那个错误。

问候,

回答

3

编译器是正确的。该变量并不总是被分配的。

如果转换失败,分配永远不会发生,并继续执行catch块,在那里你再次调用该函数里面,你却已经忘记来指派调用变量的返回值:

catch (Exception ex) 
{ 
    Console.WriteLine("Please enter a numeric value.\n"); 
    intRes = readValue(strPrompt); 
} 

下面是一个使用whileTryParse的anternative实现:

static int readValue(string strPrompt) { 
    int intRes = 0; 
    bool done = false; 
    while (!done) { 
    Console.WriteLine(strPrompt); 
    if (Int32.TryParse(Console.ReadLine(), out intRes) { 
     done = true; 
    } else { 
     Console.WriteLine("Please enter a numeric value.\n"); 
    } 
    } 
    return intRes;  
} 
+0

这解决了我的问题并回答了我的问题。 –

+0

@AbijeetPatro - 是的,这是直接的答案。但递归ReadValue()不是一个好主意。 –

+0

@HenkHolterman为什么?会做的更好吗? –

3

因为如果尝试失败,intRes没有价值

在你钓到的鱼使用

intRes = readValue(strPrompt); 

int intRes = 0; 

,而不是

初始化它
int intRes; 

您可能也想看看int.TryParse语法

+0

@Oded:其实它不会。它是一个局部变量,所以它被分配到堆栈上,并没有被初始化为任何特定的值。 – Guffa

+0

但是,如果失败了,控制将永远不会结束?它是递归的,只有当try块不抛出异常时才会结束。我想编译器还不够聪明,现在就明白这一点。 –

+0

将变量初始化为零意味着如果第一次转换失败,该函数将始终返回零。 – Guffa

3

如果Convert.ToInt32失败,系统intRes永远不会被分配给。

在创建变量时设置默认值,或者在catch块中设置默认值。

1

编译器无法知道try块内的代码是否会引发异常。
所以,如果你的代码抛出一个异常,那么intRes变量将永远不会被分配。

因此,编译器会发出错误消息。

另外,就目前而言,您的代码有问题。您尝试递归调用catch块内的readValue以获取正确的值,但是当用户最终输入正确的值时,main将永远不会收到输入的值,因为您正在使用局部变量作为结果值。

2

,你会得到一个未如果Console.ReadLine()引发异常,则初始化为intRes。这就是你的编译器抱怨的原因。

相关问题