主动抛出异常与Rethrowing vs Wrapping和Rethrowing

时间:2017-09-13 14:57:58

标签: c# exception

如果我有一个类可以导致异常,那么在方法执行之前,当我知道某些错误时,最好抛出一个异常,即:

public class FileThingy
{
    public void Do(string filepath)
    {
        if(!File.Exists(filepath))
        {
            throw new ArgumentException("File not here!");
        }   

        // do file stuff
    }
}

或等到我期待的异常发生时抛出它:

public class FileThingy
{
    public void Do(string filepath)
    {
        try
        {
            // do file stuff stuff
        } 
        catch (FileNotFoundException ex)
        {
            throw;
        }
    }
}

或者等到我期待的异常发生并将其包装在更好地描述它的类型的新异常中,然后抛出它:

public class FileThingy
{
    public void Do(string filepath)
    {
        try
        {
            // do file stuff
        } 
        catch (FileNotFoundException ex)
        {
            throw new ArgumentException("File not here!", ex);
        }
    }
}

我已经看到所有这些都被用于各个地方,并且想知道是否应该优先考虑这些中的任何一个,如果这些中的任何一个特别有害。

2 个答案:

答案 0 :(得分:2)

快速失败是最好的策略,只要您不依赖于对代码不透明的实现细节。

如果您的代码访问特定文件,并且该文件必须存在,则检查此先决条件至关重要。只要您知道问题就立即报告问题,这样可以更轻松地将问题诊断给运行代码的人。

请注意,您还需要捕获异常,因为该文件可能会在您检查其存在的时刻与您实际需要读取其内容的那一刻之间被删除。

如果打开文件是您的代码在检查文件存在后所做的第一件事,那么最好跳过检查。另一方面,如果您的代码在到达实际打开文件的位置之前检索其他数据,那么主动检查是个好主意。

如果您打算调用一些您知道将要读取特定文件的其他方法,那么主动检查该文件是否存在并不是一个好主意。较新的方法实现可以从阅读文件中切换,例如,访问数据库,使您的支票无效,并强制您更改代码。

答案 1 :(得分:2)

我认为一般规则是捕获可以优雅处理的异常,允许您无法处理的异常来冒泡堆栈并记录您抛出的任何异常,包括如何避免它们。