2012-03-20 156 views
2

這種代碼通常在PHP中工作,但是由於範圍在C#中要嚴格得多,事實並非如此。我無法想出一種不重複自己的方式來編寫這段代碼。C#變量作用域和「switch」語句?

static double Cube() 
    { 
     Console.Write("Enter the side length of the cube: "); 
     try 
     { 
      double x = Convert.ToDouble(Console.Read()); 
      return Math.Pow(x, 3); 
     } 
     catch (FormatException) 
     { 
      Console.WriteLine("Invalid input, please enter a number."); 
      Cube(); 
     } 
     return 1; 
    } 

..Later在main():

  switch (choice) 
      { 
       case 0: 
        return; 
       case 1: 
        double final = Cube(); 
        break; 
       default: 
        Console.WriteLine("Please enter 0 or 1."); 
        Main(); 
        break; 
      } 
      Console.WriteLine("The volume is: {0}", Convert.ToString(final)); 

Cube()方法工作得很好,但它在我看來凌亂(return 1末使編譯器高興)。但出現錯誤提示名稱'final'在當前上下文中不存在。它無法找到最終的。因此,讓我看到的這個工作的唯一方法是在double final = Cube()後面放置Console.WriteLine語句。

我也試過在開關外面聲明double final;,然後在每種情況下只設置final,但那也沒有奏效。

謝謝!

+1

「還沒有工作」(與其他事情嘗試)是錯誤的/誤導。他們會1)工作或2)導致不同的錯誤。 – 2012-03-20 00:26:49

+0

因爲你對Cube的定義很混亂,你必須把'return 1'。它做了太多的事情,並且你在catch中使用遞歸也不是很乾淨。該函數必須返回一個值,所以你任意選擇1作爲失敗返回。如果你不喜歡那樣,移動Math.Pow並決定你在哪裏可以真正得到正確的錯誤行爲。 – CodexArcanum 2012-03-20 00:34:08

回答

4

如果您想從switch範圍之外訪問final,則必須在該範圍之外聲明它。如果您參考了final,並且有代碼路徑不允許將值設置爲final,那麼編譯器將會「生氣」。

在php中,final在你沒有分配任何東西時會奇蹟般地爲0。嘗試在切換前聲明final,然後在每個case聲明(包括default個案)中爲其分配一個值。

+0

這樣做,謝謝! – Scott 2012-03-20 00:27:04

2

將您的開關語句之前的變量聲明:

double final = 0.0; 
switch(choice) 
{ 
    ... 
} 

然後,只需使用該變量的switch語句:

case 1: 
    final = Cube(); 
    break; 

在C#中,變量必須聲明就可以使用它們之前。在您的代碼中,聲明僅限於switch語句的範圍。在switch語句之前聲明變量可確保它在方法的範圍內,從而允許在switch語句內部和之後使用它。

19

你說得對:這是一團糟。重來。

你的根本問題是你沒有分開你的擔憂。您有一種方法可以同時進行用戶輸入,輸入驗證,重試邏輯和數學運算。你應該爲每個人製作方法。

另外,使用TryParse來處理失敗的情況,而不是異常處理。

最後,遞歸是完全錯誤的使用工具。一個問題必須具有以下特點通過遞歸來解決:

  • 甲瑣碎基礎案例。
  • 可以簡化爲一組較小的問題。
  • 小問題的解決方案可以結合使用來解決更大的問題。
  • 重複製作一個更小的問題最終會變成一件小事。

你的問題具有這些特性的沒有,所以遞歸是自動錯誤的工具。你想要的工具是循環

static void Main() 
{ 
    double x = ObtainDoubleFromUser(
     "Enter the side length of the cube: ", 
     "Please enter a number: "); 
    Console.WriteLine("The volume is {0}", Cube(x)); 
} 

static double ObtainDoubleFromUser(string firstMessage, string failureMessage) 
{ 
    Console.Write(firstMessage); 
    while(true) 
    { 
     double result; 
     if (Double.TryParse(Console.Read(), out result)) 
      return result; 
     Console.Write(failureMessage); 
    } 
} 

static double Cube(double x) 
{ 
    return Math.Pow(x, 3); 
} 

這一切都有意義嗎?如果可能的話,你想避免遞歸和異常處理。並保持你的關注分離。

+0

我只想在12月份完全錯過這個夢幻般的答案而感到歉意 - 我喜歡認爲自己已經超越了'給予代碼'的程序員,因爲我明顯是當我發佈這個問題時。謝謝! – Scott 2015-03-28 01:26:06