C# C“using”语句和try/catch

C# C“using”语句和try/catch,c#,winforms,.net-3.5,exception-handling,using-statement,C#,Winforms,.net 3.5,Exception Handling,Using Statement,我今天一直在研究何时使用using语句处理sql对象。 然而,我仍然对何时以及如何捕捉不可预见的错误感到困惑。我有一个简单的方法在这里,并将感谢任何输入,它是正确的还是我做错了什么 private BindingList<My_Object> Search(int ID) { string strSelectStatement = "SELECT 'coloumns' " + "FROM 'table' " + "WHERE ID = @ID;"

我今天一直在研究何时使用using语句处理sql对象。 然而,我仍然对何时以及如何捕捉不可预见的错误感到困惑。我有一个简单的方法在这里,并将感谢任何输入,它是正确的还是我做错了什么

private BindingList<My_Object> Search(int ID)
{
   string strSelectStatement = 
     "SELECT 'coloumns' " +
     "FROM 'table' " +
     "WHERE ID = @ID;";

     DataTable dt = new DataTable();
     try
     {
        using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
        {
          using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
          {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
            using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
            {
               adpt.Fill(dt);
            }
          }
        }

        My_Object myObject;
        BindingList<My_Object> myObjectList = new BindingList<My_Object>();

        foreach (DataRow row in dt.Rows)
        {
          myObject = new My_Object();
          //Fill/set myObject properties and add to myObject list
        }

        return myObjectList;
     }
     catch (Exception)
     {
        //throw the the exception with its stack trace up to the main call
        throw;
     }
}
所以,我在这里的捕获就是在运行adapter.Fill时,或者在构建myObject/list时,如果出现任何错误,就捕获一个错误


谢谢

不要抓住“未预料到的”错误,因为如果真的是未预料到的,你将无能为力

当然,除非您希望以某种方式处理这些错误,例如,记录消息,但系统会为您这样做,否则它们不再是“不可预见的”,因为您正期待着它们


至于发布的代码,存在一些问题。首先,try/catch可以说是尝试得太多了,考虑到其中包含using,如果不处理异常,这是毫无意义的。它还捕获了一个通用的异常,这是非常不鼓励的;渔获物应该按照适当的顺序进行配方设计,以过滤你能处理的渔获物。捕获只是为了抛出也是毫无意义的。

您可以在try语句末尾捕获多个异常。这意味着您可以捕获可能发生的每种不同类型的错误,即InvalidOperationException/SqlException。MSDN在此解释:


你不需要试一试..抓住{扔}。这与根本没有try..catch块是一样的

如果要记录显示友好消息的错误,请将代码放在catch{}中


即使代码崩溃,仍将在SqlConnection上调用Dispose。如果您对此无能为力,请不要捕获异常。如果捕获它们是为了清理非托管资源或用于日志记录目的


您可以查看MSDN处理异常的最佳实践

,因为您已将整个代码包含在try/Catch中,它将捕获try/Catch代码块中引发的所有错误。 但是不要遵循这种方法,只捕获那些您想要处理或记录的错误。
这是推荐的,因为捕获错误是一种开销。

在C中。using语句定义要处理的项的范围。这可以为实现IDisposable接口的任何对象调用

因此,如果必须不使用usingblocks,则可以调用类上的dispose方法来释放/清理对象创建的资源

调用实现IDisposable接口的类时,try/finally模式确保即使异常中断应用程序,也会释放非托管资源

如果在using语句中引发异常,则仍将调用dispose。还可以使用语句进行堆栈

using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
          {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
            using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
            {
               adpt.Fill(dt);
            }
          }
关于异常处理。捕获所有异常并不是明智的尝试捕获由类或方法引发的特定异常。您可以查看msdn so SQLConnection上的异常详细信息:

无效操作例外 未指定数据源或服务器,无法打开连接

连接已打开

SqlException 打开连接时发生连接级别错误。如果Number属性包含值18487或18488,则表示指定的密码已过期或必须重置。有关详细信息,请参阅ChangePassword方法


所以这些是你应该考虑的例外情况。希望有帮助

如果我使用using语句和try/catch块的方法正确。啊,好吧,我似乎理解using,因为它基本上是在编写try/FILLING语句,但我需要对正确的异常处理做更多的研究。^^^是的,我有一个try/FILLING first,我在FILLING子句中手动处理了我的对象,但今天决定改为使用语句,对我来说似乎更干净。在我的示例中,我使用SqlConnection、SqlCommand和SqlDataAdapter语句堆叠了3个:谢谢您的帮助!