是否需要在C#中显式引发异常?

时间:2019-07-03 22:18:25

标签: c# exception try-catch

是否需要在try块中明确抛出异常?如果我没有在try块中抛出异常会怎样?

try
{
    // code that throws an exception
    throw new IndexOutofRangeException;
}
catch (IndexOutOfRangeException ex)    
{
   Console.WriteLine(ex.Message);
}

编辑:具体来说,假设try块中有代码生成了异常,而try块却没有没有具有throw语句。会发生什么?

3 个答案:

答案 0 :(得分:2)

OP:

throw new IndexOutofRangeException;

这甚至会进行编译(没有括号)。

如果您的域中发生意外异常,则应引发异常,并应将它们捕获在您知道如何处理它们的地方。

您写道:

  

“ try块中有一些代码会生成异常,但是try块没有throw语句。会发生什么?”。

如果异常类型和模式匹配与抛出的异常相对应,则异常将在堆栈中冒泡,并且您的catch语句将执行。

答案 1 :(得分:2)

  

如果我没有在try块中抛出异常会怎样?

如果不引发异常,并且没有引发其他异常,则catch块将不会运行。该代码将改为跳过catch块,并继续执行随后发生的任何事情(包括finally块,如果有的话)。

  

想象一下,try块中有代码会生成异常,但是try块中没有throw语句。

当且仅当类型异常与catch块声明的类型匹配时,catch块仍将运行。让我们看几个例子。首先是这个样本:

try
{
   double x = 1 / 0.0;
}
catch (DivideByZeroException ex)
{
    Console.WriteLine(ex.Message);
} 

在这种情况下,我们有导致DivideByZeroException异常的代码。由于这与catch块中使用的类型匹配,因此将运行异常处理程序。

下一步:

try
{
   double x = 1 / 0.0;
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
} 

我们仍然有一个DivideByZeroException异常...但是由于DivideByZeroException是从基本Exception类型继承的,因此仍然兼容,并且catch块将运行。

另一个:

try
{
   double x = 1 / 0.0;
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message);
} 

我们仍然有一个DivideByZeroException异常,但是这次catch块是兼容的。在这种情况下,由于未处理的异常(除非此异常在程序堆栈中的其他位置处理),程序将崩溃

一个:

try
{
   double x = 1 / 0.0;
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message);
} 
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

两个catch块!第一个块将不运行,因为它与DivideByZeroException类型不兼容。但是,第二个catch块将运行,因为它是兼容的。处理异常,程序可以继续。

最后:

double DbyZ(double numerator)
{
    try 
    {
        return numerator / 0.0;
    }
    catch(InvalidOperationException ex)
    {
        Console.WriteLine("Invalid operation");
    }
} 

...

try
{
     DbyZ(1.0);
}
catch(Exception ex)
{
    Console.WriteLine("Exception");
}

这次,输出将仅为"Exception"。请记住,您不必总是在引发异常的地方捕获异常。

如果您仍然对某个案例可能发生的事情有疑问,请创建自己的示例以测试案例并查看。

答案 2 :(得分:-1)

如果代码创建了一个异常但没有引发异常,则try / catch看不到它。引发异常是使异常与任何其他类类型不同的唯一原因。

.NET例外是软件工件。尽管它们中的许多都与硬件陷阱或OS错误相对应,但是硬件不会产生,生成或引发.NET异常对象。发生的情况是,.NET运行时引擎中的代码正在检测其他错误,然后创建并引发.NET异常对象,并将较低级别的错误信息转换为.NET异常的属性。

可以通过事件驱动的方式来调用该转换/包装代码,例如,通过安装Windows结构化异常处理的处理程序,而不是使用代码来测试浮点NaN的每个算术结果。但是它仍然是软件。作为一个具体示例,在乔尔的答案中,代码1 / 0.0不会生成DivideByZeroException。它生成FPU异常,并且公共语言运行库处理该FPU异常。是CLR中的处理程序创建并抛出DivideByZeroException实例并落入您的catch块中。