如何操纵程序来处理异常

时间:2015-03-12 12:23:04

标签: c# exception

所以目前我正在写一个类似的程序:

try
{
    mainprocessing();
}
catch (exception e)
{
    //first catch block.
    //do something here
}

mainprocessing()
{
    try
    {
        string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
    }
    catch (NullReferenceException e) 
    {
        //second catch block
        //something here to handle it
    }
}

但是当我现在运行程序时,如果string value为空,则异常将在first catch block中处理。但是我希望它在second catch block中处理。有没有办法操纵这个?

3 个答案:

答案 0 :(得分:0)

没有以正确的方式阅读问题,认为你想明确进入顶级例外。

当一个值为null并尝试访问此变量时,将不会引用实际对象,因此将抛出NullReferenceException但在这种情况下,您将为引用分配值,因此抛出另一个异常而不是NullReferenceException异常。

找出抛出了哪个Exception的唯一方法是在NullReferenceException下面添加另一个catch块。

catch (NullReferenceException e) 
{
    //second catch block
    //something here to handle it, LOG IT!
}
catch (Exception exception)
{
    Type exceptionType = exception.GetType();
}

当程序处理(捕获)异常时,它返回到调用此函数的位置,在这种情况下是' mainprocessing'。

如果您明确想要进入最顶级的异常处理块,只需在catch中抛出一个新的Exception,如下所示:

mainprocessing()
{
    try
    {
        string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
    }
    catch (NullReferenceException e) 
    {
        //second catch block
        //something here to handle it, LOG IT!
        throw new Exception("top level exception");
    }
}

答案 1 :(得分:0)

如评论中所述,处理异常不是处理C#中的流控制的方法。如果出现意外情况,您可以使用它们,在开始处理之前无法提前检查(例如文件已损坏且您的读取意外中止)。

在您的情况下,只需使用简单的if检查:

string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");

if (string.IsNullOrWhiteSpace(value))
{
    // Handle the null/empty string here.
    // From what you said probably the logic you wanted to use in your second catch block.
}

修改

要在ReadCell级别处理异常,只需在访问该值之前检查它是否为null。那你有几个选择。您可以中止执行(return)或尝试获取ReadCell的实例。

if (ReadCell == null)
{
     // abort the execution, create 
}

string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");

或者只是缩进几个if s:

if (ReadCell != null)
{
    string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");

    if (string.IsNullOrWhiteSpace(value))
    {
        // Handle the null/empty string here.
        // From what you said probably the logic you wanted to use in your second catch block.
    }
}
else
{
    // Handle null case for ReadCell.
}

答案 2 :(得分:0)

以下是您应该如何处理特定情况中的异常:

    private void btnDataStuff_Click(object sender, EventArgs e)
    {
        try
        {
            ProcessSomeData();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
            MessageBox.Show("Inner exception: " + ex.InnerException.Message);
        }
    }

    private void ProcessSomeData()
    {
        try
        {
            // Code where NullReferenceException exception happens
        }
        catch (NullReferenceException ex)
        {
            throw new ApplicationException("Data is null!!!", ex);
        }
    }

这是处理和传播异常的正确方法。我认为这是你原本想要完成的。如果NullReferenceException方法中发生ProcessSomeData异常,则会将其作为新Data is null!!!消息传播,但也会保留原始异常因为它存储了以后调试的关键信息(调用堆栈等)。这样,您可以在应用程序中为最终用户原始异常提供“好”错误消息,以便程序员根据需要进行调试。

这是一个非常简单的例子。请阅读this to learn best practices when handling exceptions。这是你必须(必须)学习的最重要的编程方面之一 - 你 会以任何方式学习它,但为什么要在你从一开始就能让你的生活更轻松的时候走上艰难的道路。 / p>

同时阅读C# coding conventions,以便您可以从一开始就编写质量代码。

其他海报暗示您应该验证null的数据而不是捕获异常,在大多数情况下这是正确的,但如果您仍然希望捕获一些特定的例外,您现在知道这样做的正确方法