【问题标题】:Try Catch C# How Do I do it?尝试 Catch C# 我该怎么做?
【发布时间】:2017-12-27 11:45:52
【问题描述】:

我正在处理一项任务,我现在必须实现 Try & Catch 方法,以便在我的程序中捕获除数字以外的输入。我了解我的学习书中的过程和解释,并且在尝试时也做了一些小例子。但是当我想在我的任务中实现这一点时,我被卡住了。有人可以在庄园里向我解释一下,不要破坏任何东西,而是一路帮助我吗?

这是我的代码:

using System;

namespace BastunKP
{
  class Program
  {
       public static double FahrToCels(double fahr)
       {
          return (fahr - 32) * 5 / 9;
       }

       public static void Main(string[] args)
       {
          Console.WriteLine("Skriv in Fahrenheit: ");
          double fahr = Convert.ToDouble(Console.ReadLine());
          double tempCels = FahrToCels(fahr);

          do            
          {      
            try               
            {
                //Dont know what to write here.
            }
            catch
            {
                Console.WriteLine("Du kan bara skriva in siffor, testa igen.");
            }

            if (tempCels < 73)
            {
                Console.WriteLine("Temperaturen är för kallt, skruva upp lite!");
            }
            else if (tempCels > 77)
            {
                Console.WriteLine("Temperaturen är för varmt, skruva ner lite!");
            }
            else 
            {
                Console.WriteLine("Temperaturen är nu bra, hoppa in!");
                Console.ReadKey();
            }

            fahr = Convert.ToDouble(Console.ReadLine());
            tempCels = FahrToCels(fahr);              
          }        
          while (tempCels < 73 || tempCels > 77);
          return;
      }
   }
}

【问题讨论】:

  • //Dont know what to write here. 无论是可能抛出异常的代码是什么。 在添加try..catch 之前,请考虑一下您计划编写的代码。这就是你应该放在try 块中的代码。
  • 首先我认为我必须有代码“double fahr = Convert.ToDouble(Console.ReadLine());”在那里,但那不起作用..
  • 在 try 之外声明你的变量。在里面,只需分配值。

标签: c# variable-assignment


【解决方案1】:

首先,让我们编写没有任何异常处理的代码。先把基础搞好。我们需要一个方法:

  1. 询问用户华氏温度。
  2. 如果输入不是有效的double,请转到1。
  3. 将值转换为摄氏度。
  4. 如果没有,请转到 1。
  5. 如果摄氏温度不属于(73, 77),则转到1。

    public static double GetTemperatureFromUser()
    {
         while (true)
         {
              Console.Write("Enter temperature in Fahrenheit: ");
              var t = FahrToCels(Convert.ToDouble(Console.ReadLine()));
    
              if (t < 73)
              {
                  Console.Write("Temperature is too low. Try again.");
              }
              else if (t > 77)
              {
                  Console.Write("Temperature is too high. Try again.");
              }
              else
              {
                  return t;
              }
         }
    }
    

好的,看起来不错。现在让我们添加一些异常处理。第一个问题:这里会出现什么问题并抛出异常?

var t = FahrToCels(Convert.ToDouble(Console.ReadLine()));

似乎是个嫌疑犯。还有什么可以扔的吗?嗯,没有。

好的,第二个问题:如果ToDouble() 抛出,什么代码不应该被执行?好吧,显然取决于ToDouble() 的结果。所以所有这些代码也都放在try 块中。

好的,第三个问题:如果ToDouble() 抛出,应该运行什么代码?在我们的例子中,我们应该通知用户输入不是有效的double。好的,该代码需要进入catch 块。

try-catch 视为控制代码执行路径的花哨的if:如果代码抛出异常,则转到catch,否则继续在try 块内正常执行。

第四个问题:无论发生什么,应该在trycatch 块内的所有其他内容之后运行什么代码?在您的情况下,没有,但如果有,它将进入 finally 块。

请注意,catchfinally 块不是强制性的。唯一的规则是至少其中一个必须紧跟在try 块之后; try-catchtry-finallytry-catch-finally 都是有效的。

第五个也是最后一个:你想处理什么异常?您应该始终只处理您知道如何处理的异常,而忽略所有其他异常。 ToDouble 可以抛出什么异常?如果您阅读文档,您会发现它可以抛出FormatExceptionOverflowException。您可以同时处理这两种情况,因为它们相当于同一件事:以及无效的用户输入。

好的,让我们重写我们的方法:

while 循环是否依赖于ToDouble 中发生的任何事情?不,无论内部发生什么,该方法都应该循环运行;退出循环的唯一方法是当用户输入一个有效数字并且方法返回时。那么,while 块超出了任何异常处理,用户提示也是如此:

public static double GetTemperatureFromUser()
{
     while (true)
     {
         Console.Write("Enter temperature in Fahrenheit: ");
         //...
     }
}

现在下一条指令是我们的主要嫌疑人,所以它显然必须进入try 块内。我们在方法中编写的所有其他内容都取决于 t 的值,因此我们将所有内容也放在 try 块中:

public static double GetTemperatureFromUser()
{
     while (true)
     {
          Console.Write("Enter temperature in Fahrenheit: ");

          try
          {
              var t = FahrToCels(Convert.ToDouble(Console.ReadLine()));

              if (t < 73)
              {
                  Console.Write("Temperature is too low. Try again.");
              }
              else if (t > 77)
              {
                  Console.Write("Temperature is too high. Try again.");
              }
              else
              {
                  return t;
              }
         }
     }
} 

好的,现在我们只缺少catch 块。我们将为每个我们知道如何处理的异常添加一个:

public static double GetTemperatureFromUser()
{
     while (true)
     {
          Console.Write("Enter temperature in Fahrenheit: ");

          try
          {
              var t = FahrToCels(Convert.ToDouble(Console.ReadLine()));

              if (t < 73)
              {
                  Console.Write("Temperature is too low. Try again.");
              }
              else if (t > 77)
              {
                  Console.Write("Temperature is too high. Try again.");
              }
              else
              {
                  return t;
              }
         }
         catch (FormatException)
         {
              Console.Write("Invalid number format. Try again.");
         }
         catch (OverflowException)
         {
              Console.Write("Number is too large or too small. Try again.");
         }
     }
} 

到此为止,我们完成了。

【讨论】:

  • 谢谢!这使代码工作!不过,有一个问题,您从哪里获取 catch 参数中的名称“FormatException”和“OverflowException”?
  • @Kian 首先,这个答案并不是要“让代码工作”,而是要让你开始理解异常处理在 c# 中是如何工作的。简单地让你的代码工作需要一个更短的答案。其次,System.FormatExceptionSystem.OverflowException 是框架中实现的类,扩展了System.Exception
【解决方案2】:

检查有效输入不需要try/catch。你可以使用double.TryParse;

Console.WriteLine("Skriv in Fahrenheit: ");
double fahr;
double tempCels;
bool isInputCorrect = false;
while (!isInputCorrect)
{
    var input = Console.ReadLine();
    if (!double.TryParse(input, out fahr))
    {
        Console.WriteLine("Du kan bara skriva in siffor, testa igen.");
        continue;
    }
    tempCels = FahrToCels(fahr);
    if (tempCels < 73)
    {
        Console.WriteLine("Temperaturen är för kallt, skruva upp lite!");
        continue;
    }
    else if (tempCels > 77)
    {
        Console.WriteLine("Temperaturen är för varmt, skruva ner lite!");
        continue;
    }
    isInputCorrect = true;
}
Console.WriteLine("Temperaturen är nu bra, hoppa in! tempCels : " + tempCels);
Console.ReadKey();

如果你坚持使用try/catch,你可以这样尝试;

只需替换 double.TryParse 部分。

var input = Console.ReadLine();
try
{
    fahr = Convert.ToDouble(input);
}
catch (Exception e)
{
    Console.WriteLine("Du kan bara skriva in siffor, testa igen.");
    continue;
}

【讨论】:

    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2017-08-26
    • 2022-06-18
    • 2010-10-07
    • 2014-01-23
    相关资源
    最近更新 更多