如果在 C# 中的 Catch 块中发生异常,会发生什么情况.在这种情况下,调用方的结果也是什么

本文关键字:这种情况下 调用 是什么 结果 什么情况 异常 中的 Catch 如果 | 更新日期: 2023-09-27 18:34:45

这是一个面试问题,很简单,但我对答案没有信心。

如果捕获块中发生异常会发生什么?

试图举一个面试官试图问我的例子,如果它没有编译,请纠正我的程序,我真的很陌生。底线是如果在 Catch 中发生异常会发生什么,以及调用者 int hat case 的值是多少。

例如,我有以下内容:

double Calculate(int x)
{
    try
    {
        x = x/2;
    }
    catch(Exception ex)
    {
        Console.Writeline("Message: "+ ex.Message);
    }
    finally
    {
      x = 10;
    }
    return x;
}
double myResult = Calculate(x); //x can be any number or 0 for example

现在有两个问题:

  1. 如果捕获块中发生异常会发生什么?另外,如何解决它?(这是面试官问类似问题的简单例子(。

  2. 如果在 Calculate(x( 方法中发生异常,myResult 会发生什么?在所有情况下,它的价值是什么?(请用一个例子解释每个案例(

我也想通过详细的解释来理解这一点。

非常感谢。

如果在 C# 中的 Catch 块中发生异常,会发生什么情况.在这种情况下,调用方的结果也是什么

catch 块中抛出的异常的行为与没有它的异常相同 - 它将在堆栈中向上移动,直到它被捕获到更高级别的 catch 块(如果存在(。如果要更改或包装原始异常,这样做是很正常的;即:

public void MyStartMethod
{
    try
    {
        //do something
        MyBadMethod();
    }
    catch(MySpecialException mse)
    {
        //this is the higher level catch block, specifically catching MySpecialException 
    }
}
public void MyBadMethod()
{
    try
    {
        //do something silly that causes an exception
    }
    catch (Exception e)
    {
        //do some logging
        throw new MySpecialException(e);
    }
}
public class MySpecialException : Exception 
{   
    public MySpecialException(Exception e) { ...etc... }
}

在您的情况下,myResult将具有它以前的任何价值,如果它仍在范围内。

catch

中的异常基本上会表现得好像一开始就没有 catch 块一样。您可以在多层代码中看到此模式,其中会重新引发异常。这与您的示例略有不同,但结果非常相似。

try
{}
catch
{
  throw;
}

在上述情况和您的情况下,异常被视为未处理,因为它仍在堆栈中向上传播。

不会有返回值。如果没有其他捕获块来处理它,程序就会失败。

下面的信息会有所帮助(来自我之前对相关问题的回答(。如果您的 catch 块抛出异常,并且除了导致它的块之外没有其他 catch 块可以处理它,它将继续被重新抛出,然后"Windows 处理它"。

如果发生异常,CLR 将遍历调用堆栈以查找 匹配的捕获表达式。如果 CLR 找不到匹配的, 或者每次都会重新抛出异常,异常会冒泡 的 Main(( 方法。在这种情况下,Windows处理异常。

控制台应用程序的事件处理是最容易理解的, 因为 CLR 没有特殊处理。例外情况是 如果未捕获,则离开应用程序线程。CLR 将打开一个窗口 请求调试或退出应用程序。如果用户选择 调试,调试器启动。如果用户选择关闭,则 应用程序退出,异常被序列化并写入 安慰。

如果是子函数,异常将被发送到调用函数的 catch 块

如果它是一个主函数,则会抛出异常,并且由调用方法处理或手动处理

其次,我们不会在可能导致异常catch块中写入任何内容。

它们通常用于引发或记录异常。

即使有一些东西,您也可以使用Finally块,以便可以释放任何占用的资源。

catch

和final在一起的常见用法是获取和使用try块中的资源,处理catch块中的异常情况,以及最终块中的资源释放。

MSDN 文档

没有真正的返回值。异常将"返回"。

这是编译器可接受的代码:

public bool fooMethod()
{
  throw new NotImplementedException();
}

在您的情况下myResult不会改变。

我同意TheEvilPenguin的观点。只需在捕获部分再尝试/捕获一次。我没有运行代码,但无论是否有异常,finally 部分都将始终运行,因此 x 等于 10。

这是我今天写的疯狂代码。如您所见,我在代码的 catch 部分放置了一个 try/catch:

                     if (days >= 180 || inStock == false)
                    {
                        if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
                        {
                            if (debugging == true)
                            {
                                MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
                            }
                            string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
                            string body = "Dear Support 'r'n 'r'nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
                            "and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
                            " 'r'n 'r'n Kind Regards, 'r'n IT Department";
                            sendEmail.SendEmailToSupport(subject, body);
                            // Database call to the cancel order DB
                            CanceledDB.AddJSONInfo(childGetSet);
                            //readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
                        }
                        MainGetSet.EMAILCANCELO = mainGetSet.OrderID;
                    }
                    else
                    {
                        if (debugging == true)
                        {
                            MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
                        }
                        //DateTime backorder180 = new DateTime().AddDays(days);
                        //string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
                        string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";
                        string ItemsQty = string.Empty;
                        for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
                        {
                            //ItemsQty += "{  'r'n        '"autoAssign'":false,'r'n        '"locationID'":169309,'r'n        '"shipmentStatus'":'"READY'",'r'n        '"itemAssign'":[  'r'n           {  'r'n              '"orderItemID'":" + jsonGetSet.OrderItemID[iq] + ",'r'n              '"quantity'":" + jsonGetSet.Quantity[iq] + "'r'n           }'r'n        ]'r'n     }'r'n";
                            ItemsQty += "    {'r'n         '"shipmentStatus'":'"BACKORDER'",'r'n         '"backOrderReleaseDate'":'"" + backOrder + "'",'r'n         '"itemAssign'":['r'n            {'r'n               '"orderItemID'":" + jsonGetSet.OrderItemID[iq] + ",'r'n               '"quantity'":" + jsonGetSet.Quantity[iq] + "'r'n            }'r'n         ]'r'n      }'r'n ";
                            if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
                            {
                                ItemsQty += ",";
                            }
                        }
                        if (debugging == true)
                        {
                            MessageBox.Show(ItemsQty);
                        }
                        string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain  the reason.";
                        string body = "Dear Support 'r'n 'r'nPlease check backorder number " + mainGetSet.OrderID + " to confirm  the backorder. " +
                            "Here is the SKU " + childGetSet.Sku + "."+
                            " 'r'n 'r'n Kind Regards, 'r'n IT Department";
                        sendEmail.SendEmailToSupport(subject, body);
                        readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
                    }
                    if (debugging == true)
                    {
                        DebugOutput(readyResponse, textBox);
                    }
                    var parsedReady = new JObject();
                    try
                    {

                        parsedReady = JObject.Parse(readyResponse);

                    }
                    catch (Exception JEx)
                    {
                        if (debugging == true)
                        {
                            MessageBox.Show("The program threw an Exception: " + JEx);
                        }
                        else
                        { 
                            string messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
                            string messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
                                "'r'n 'r'n 'r'n Here is the JSON returned: " + parsedReady;
                            string kiboSendEmail = string.Empty;
                            kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);
                            if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
                            {
                                if (debugging == true)
                                {
                                    MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
                                }
                                string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
                                string body = "Dear Support 'r'n 'r'nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
                                "and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
                                " 'r'n 'r'n Kind Regards, 'r'n IT Department";
                                sendEmail.SendEmailToSupport(subject, body);
                                // Database call to the cancel order DB
                                CanceledDB.AddJSONInfo(childGetSet);
                                //readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
                            }
                            MainGetSet.EMAILCANCELO = mainGetSet.OrderID;

                            {
                            if (debugging == true)
                            {
                                MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
                            }
                            //DateTime backorder180 = new DateTime().AddDays(days);
                            //string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
                            string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";
                            string ItemsQty = string.Empty;
                            for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
                            {
                                //ItemsQty += "{  'r'n        '"autoAssign'":false,'r'n        '"locationID'":169309,'r'n        '"shipmentStatus'":'"READY'",'r'n        '"itemAssign'":[  'r'n           {  'r'n              '"orderItemID'":" + jsonGetSet.OrderItemID[iq] + ",'r'n              '"quantity'":" + jsonGetSet.Quantity[iq] + "'r'n           }'r'n        ]'r'n     }'r'n";
                                ItemsQty += "    {'r'n         '"shipmentStatus'":'"BACKORDER'",'r'n         '"backOrderReleaseDate'":'"" + backOrder + "'",'r'n         '"itemAssign'":['r'n            {'r'n               '"orderItemID'":" + jsonGetSet.OrderItemID[iq] + ",'r'n               '"quantity'":" + jsonGetSet.Quantity[iq] + "'r'n            }'r'n         ]'r'n      }'r'n ";
                                if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
                                {
                                    ItemsQty += ",";
                                }
                            }
                            if (debugging == true)
                            {
                                MessageBox.Show(ItemsQty);
                            }
                            string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain  the reason.";
                            string body = "Dear Support 'r'n 'r'nPlease check backorder number " + mainGetSet.OrderID + " to confirm  the backorder. " +
                                "Here is the SKU " + childGetSet.Sku + "." +
                                " 'r'n 'r'n Kind Regards, 'r'n IT Department";
                            sendEmail.SendEmailToSupport(subject, body);
                            readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
                        }
                        if (debugging == true)
                        {
                            DebugOutput(readyResponse, textBox);
                        }
                        parsedReady = new JObject();
                        try
                        {

                            parsedReady = JObject.Parse(readyResponse);

                        }
                        catch (Exception Jx)
                        {
                            if (debugging == true)
                            {
                                MessageBox.Show("The program threw an Exception: " + Jx);
                            }
                            else
                            {
                                messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
                                messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
                                    "'r'n 'r'n 'r'n Here is the JSON returned: " + parsedReady;
                                kiboSendEmail = string.Empty;
                                kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);



                            }
                        }

解释它代码明智。这是示例代码使用系统;

public class Program
{
    public static double Calculate(int x)
    {
        try
        {
            x = 2 / x;
        }
        catch (ArithmeticException ae)
        {
            x = 2 / x;  // This will throw the error and programs terminates without returning any value.
            Console.WriteLine("Message: " + ae.Message);
        }
        catch (Exception ex)
        {                
            Console.WriteLine("Message: " + ex.Message);
        }
        finally
        {
            x = 10;
        }
        return x;
    }
    static void Main(string[] args)
    {
        double myResult = Program.Calculate(0);
        Console.WriteLine(myResult);
    }
}
}

即使代码在 catch 块中,代码的行为也是一样的,除非像这样的 catch 块中有 try catch

public class Program
{
    public static double Calculate(int x)
    {
        try
        {
            x = 2 / x;
        }
        catch (ArithmeticException ae)
        {
            try
            {
                x = 2 / x;
            }
            catch(Exception ex1)
            {
                Console.WriteLine("Message: " + ex1.Message);
            }
            Console.WriteLine("Message: " + ae.Message);
        }
        catch (Exception ex)
        {                
            Console.WriteLine("Message: " + ex.Message);
        }
        finally
        {
            x = 10;
        }
        return x;
    }
    static void Main(string[] args)
    {
        double myResult = Program.Calculate(0);
        Console.WriteLine(myResult);
    }
}
}