2012-09-03 157 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。這就是你的編譯器抱怨的原因。

相關問題