3

ReSharper 建议重新抛出异常,然后,当我这样做时,它会说整个 catch 子句无论如何都是多余的,并建议将其删除。

我正在使用此代码(来自 MethodMan here):

public static DataTable ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters)
{
    using (DataSet ds = new DataSet())
    using (SqlConnection connStr = new SqlConnection(UsageRptConstsAndUtils.CPSConnStr))
    using (SqlCommand cmd = new SqlCommand(sql, connStr))
    {
        cmd.CommandType = cmdType;
        foreach (var item in parameters)
        {
            cmd.Parameters.Add(item);
        }

        try
        {
            cmd.Connection.Open();
            new SqlDataAdapter(cmd).Fill(ds);
        }
        catch (SqlException ex)
        {
            throw;
        }
        return ds.Tables[0];
    }
}

当我有 ReSharper Inspect > Code Issues in Solution 时,它想知道“异常重新抛出可能是有意的”:

catch (SqlException ex)
{
    throw ex;
}

如果我接受 ReSharper 建议的修复(“重新抛出异常”),Resharper 会删除“ex”:

catch (SqlException ex)
{
    throw;
}

...但是,在下一次检查中,它说“catch 子句是多余的”并建议将其完全删除。

但是,当然,如果我删除了 catch 块,它就不会编译(“预期的 catch 或 finally”)。我可以删除尝试...但是...如果我将其更改为:

                catch (SqlException sqlex)
                {
                    for (int i = 0; i < sqlex.Errors.Count; i++)
                    {
                        var sqlexDetail = String.Format("From
ExecuteDataSet(), SQL Exception #{0}{1}Source: {2}{1}   
Number: {3}{1}State: {4}{1}Class: {5}{1}Server: {6}{1}Message: {7}
{1}Procedure: {8}{1}LineNumber: {9}",
                            i + 1, // Users would get the fantods if they
saw #0
                            Environment.NewLine,
                            sqlex.Errors[i].Source,
                            sqlex.Errors[i].Number,
                            sqlex.Errors[i].State,
                            sqlex.Errors[i].Class,
                            sqlex.Errors[i].Server,
                            sqlex.Errors[i].Message,
                            sqlex.Errors[i].Procedure,
                            sqlex.Errors[i].LineNumber);
                        MessageBox.Show(sqlexDetail);
                    }
                }
                catch (Exception ex)
                {
                    String exDetail
String.Format(UsageRptConstsAndUtils.ExceptionFormatString, ex.Message, 

Environment.NewLine, ex.Source, ex.StackTrace);
                    MessageBox.Show(exDetail);
                }

...ReSharper 的检查并没有抱怨它。

4

2 回答 2

6

执行此操作时,您正在重置调用堆栈,这会丢失有关最初引发异常的重要信息。

catch (SqlException ex)
{
    throw ex;
}

如果 ReSharper 更智能,它会告诉您一开始就删除该部分,从而节省您重写该部分代码的时间。

以下代码更好,因为它不会丢失堆栈跟踪信息,但它是不必要的。

catch (SqlException ex)
{
    throw;
}

即使您省略了上述内容,异常也会“冒泡”,并且可以在程序中堆栈的某个位置被捕获,无论您准备实际处理它(记录它,或显示一条消息,或采取一些替代行动等)。

于 2015-11-23T19:44:20.667 回答
1
catch (SqlException ex)
{
    throw ex;
}

是一种糟糕的编程习惯。您会从抛出的异常中丢失原始堆栈跟踪。

catch (SqlException ex)
{
   throw;
}

除了浪费时间重新抛出相同的异常之外,对您没有任何帮助。Re-sharper 期望你对变量 ex 做一些事情,比如记录它。

于 2015-11-23T19:44:21.703 回答