关于使用/try/catch的真正编码约定

本文关键字:编码 约定 catch 于使用 try | 更新日期: 2023-09-27 18:12:41

让我们假设我有这样的代码:

internal static bool WriteTransaction(string command)
{
    using (SqlConnection conn = new SqlConnection(SqlConnectionString))
    {
        try
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand(command, conn))
               cmd.ExecuteNonQuery();
        }
        catch { return false; }
    }
    return true;
}

嗯,我已经把conn的using放在try/catch子句之外,因为SqlConnection的构造函数不会抛出任何异常(正如它所说)。因此,conn.Open()在子句中,因为它可能抛出一些异常。

现在,这是正确的编码方法吗?看:SqlCommand的构造函数也不抛出异常,但为了减少代码,我把它和cmd.ExecuteNonQuery()一起放在try/catch里面。

也许这个应该在那里?

internal static bool WriteTransaction(string command)
{
    using (SqlConnection conn = new SqlConnection(SqlConnectionString))
    {
        try { conn.Open(); }
        catch { return false; }
        using (SqlCommand cmd = new SqlCommand(command, conn))
            try { cmd.ExecuteNonQuery(); }
            catch { return false; }
    }
    return true;
}

(不好意思我的英文)

关于使用/try/catch的真正编码约定

除非您能以某种有意义的方式处理异常,否则不要捕获它。相反,让它在调用堆栈中向上传播。

例如,在什么条件下SqlCommand ExecuteNonQuery()可以抛出异常?一些可能是sql查询格式不正确,无法执行或您失去了与数据库服务器的连接。你不会想用同样的方法处理它们,对吧?

您应该考虑处理的一个例外是SQLException死锁(错误号1205)。

正如在注释中指出的那样,您至少应该记录异常。

[BTW, WriteTransaction()可能是一个糟糕的名称,为该方法,考虑到您所显示的代码]

您的第一个代码示例,只有一个try-catch块,与第二个代码示例等效。然而,第一个更容易阅读和更短。


值得记住的是,通常的c#编码方法是不捕获异常,除非在代码的最顶层。

这里有一个写得很好的参考:http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx.

在您的情况下,这将简化您的代码:而不是返回一个bool值来指示方法成功或失败,然后进行测试,您通过使方法无效并仅在顶级异常处理程序中处理意外异常来"假设最好"。

写入数据库的异常处理可以被认为是这条一般规则的一个轻微例外:但我个人的方法是专门针对并发问题进行捕获,如果发生这种情况,请重试几次。

我认为你的第一个解决方案是更好的,因为如果你得到一个错误,建立连接是没有用的,试图在该连接上执行命令。
因此,第一个解决方案,如果你得到一个错误,你直接去做catch块,然后处置对象,而第二个你经历两个异常,重载内存无用。

与良好的catch子句(异常日志),你真的不需要2x try块,1是足够的

…你的第二种方法是错误的-有没有需要try catch打开连接-因为即使你抓住这个你无论如何都做了-你不能执行查询。在catch块中,您可以尝试"修复"该问题,但它会给您什么- catch中的while循环?

第一种方法更可取,原因很简单:方法的两个版本在行为方面是相同的,但第一个版本需要更少的代码。

有时就像计算代码行数一样简单;-)…

HTH !

注:我不会在这个方法中有一个try/catch语句,但我会把它放在一个更高的级别,在这个内部方法被调用。

给定您的方法'WriteTransaction'正在吞噬所有异常并返回事务的成功,或者没有,那么我会在整个方法周围使用一个try/catch块。

internal static bool WriteTransaction(string command) {
    try {
        using (SqlConnection conn = new SqlConnection(SqlConnectionString)) {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand(command, conn)) {
                cmd.ExecuteNonQuery();
            }
        }
    }
    catch { 
        return false; 
    }
    return true;
}

现在你应该问问自己,捕捉所有异常并返回真/假是否是正确的做法。在生产环境中,如果没有记录异常,您将如何诊断和修复错误?