这是一个面试问题,很简单,但我对答案没有信心。
如果捕获块中发生异常会发生什么?
我试图举一个面试官试图问我的例子,如果它没有编译,请纠正我的程序,我真的很陌生。底线是如果在 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
现在有两个问题:
如果捕获块中发生异常会发生什么?另外,如何解决它?(这是面试官问类似问题的简单例子(。
如果在 Calculate(x( 方法中发生异常,myResult 会发生什么?在所有情况下,它的价值是什么?(请用一个例子解释每个案例(
我也想通过详细的解释来理解这一点。
非常感谢。
在 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 块一样。您可以在多层代码中看到此模式,其中会重新引发异常。这与您的示例略有不同,但结果非常相似。
try
{}
catch
{
throw;
}
在上述情况和您的情况下,异常被视为未处理,因为它仍在堆栈中向上传播。
不会有返回值。如果没有其他捕获块来处理它,程序就会失败。
下面的信息会有所帮助(来自我之前对相关问题的回答(。如果您的 catch 块抛出异常,并且除了导致它的块之外没有其他 catch 块可以处理它,它将继续被重新抛出,然后"Windows 处理它"。
如果发生异常,CLR 将遍历调用堆栈以查找 匹配的捕获表达式。如果 CLR 找不到匹配的, 或者每次都会重新抛出异常,异常会冒泡 的 Main(( 方法。在这种情况下,Windows处理异常。
控制台应用程序的事件处理是最容易理解的, 因为 CLR 没有特殊处理。例外情况是 如果未捕获,则离开应用程序线程。CLR 将打开一个窗口 请求调试或退出应用程序。如果用户选择 调试,调试器启动。如果用户选择关闭,则 应用程序退出,异常被序列化并写入 安慰。
如果是子函数,异常将被发送到调用函数的 catch 块
如果它是一个主函数,则会抛出异常,并且由调用方法处理或手动处理
其次,我们不会在可能导致异常catch
块中写入任何内容。
它们通常用于引发或记录异常。
即使有一些东西,您也可以使用Finally
块,以便可以释放任何占用的资源。
和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 rn rnPlease 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. " +
" rn rn Kind Regards, rn 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 += "{ rn "autoAssign":false,rn "locationID":169309,rn "shipmentStatus":"READY",rn "itemAssign":[ rn { rn "orderItemID":" + jsonGetSet.OrderItemID[iq] + ",rn "quantity":" + jsonGetSet.Quantity[iq] + "rn }rn ]rn }rn";
ItemsQty += " {rn "shipmentStatus":"BACKORDER",rn "backOrderReleaseDate":"" + backOrder + "",rn "itemAssign":[rn {rn "orderItemID":" + jsonGetSet.OrderItemID[iq] + ",rn "quantity":" + jsonGetSet.Quantity[iq] + "rn }rn ]rn }rn ";
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 rn rnPlease check backorder number " + mainGetSet.OrderID + " to confirm the backorder. " +
"Here is the SKU " + childGetSet.Sku + "."+
" rn rn Kind Regards, rn 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: " +
"rn rn rn 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 rn rnPlease 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. " +
" rn rn Kind Regards, rn 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 += "{ rn "autoAssign":false,rn "locationID":169309,rn "shipmentStatus":"READY",rn "itemAssign":[ rn { rn "orderItemID":" + jsonGetSet.OrderItemID[iq] + ",rn "quantity":" + jsonGetSet.Quantity[iq] + "rn }rn ]rn }rn";
ItemsQty += " {rn "shipmentStatus":"BACKORDER",rn "backOrderReleaseDate":"" + backOrder + "",rn "itemAssign":[rn {rn "orderItemID":" + jsonGetSet.OrderItemID[iq] + ",rn "quantity":" + jsonGetSet.Quantity[iq] + "rn }rn ]rn }rn ";
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 rn rnPlease check backorder number " + mainGetSet.OrderID + " to confirm the backorder. " +
"Here is the SKU " + childGetSet.Sku + "." +
" rn rn Kind Regards, rn 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: " +
"rn rn rn 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);
}
}
}