如果“;尝试“;在资源分配之前或之后

本文关键字:或之后 尝试 如果 资源分配 | 更新日期: 2023-09-27 18:29:15

在Delphi世界中,至少有人认为,最好在资源分配之后进行尝试,例如:

OracleCommand oc = new OracleCommand(query, con);
try
begin
  oc.CommandType = CommandType.Text;
  String s = oc.ExecuteScalar().ToString();
  try            
    return s;            
    except (on OracleException ex)
    begin
      ShowMessage(ex.Message);
      result := string.Empty;
    end;
end
finally
begin
  con.Close();
  con.Dispose();
end;

它在C#中是一样的,还是应该在资源分配之前进行"尝试":

try
{
  OracleCommand oc = new OracleCommand(query, con);
  oc.CommandType = CommandType.Text;
  String s = oc.ExecuteScalar().ToString();
  try
  {
    return s;
  }
  catch (OracleException ex)
  {
    MessageBox.Show(ex.Message);
    return string.Empty;
  }
}
finally
{
  con.Close();
  con.Dispose();
}

如果“;尝试“;在资源分配之前或之后

还有一个更好的解决方案:using语句。代替此代码,您可以编写惯用的

using (Connection con = /* some initialization logic */)
{
    try
    {
        using (OracleCommand oc = new OracleCommand(query, con))
        {
            oc.CommandType = CommandType.Text;
            return oc.ExecuteScalar().ToString();
        } // oc is automatically disposed here
    }
    catch (OracleException ex)
    {
        MessageBox.Show(ex.Message);
        return string.Empty;
    }
} // con is automatically disposed here

在C#中,去掉你内心的尝试,这是不必要的,因为我从未见过return会这样失败。您也可以对一次性类型使用using语句,即使发生异常,它也会调用Dispose

try
{
    using(OracleCommand oc = new OracleCommand(query, con))
    {
        oc.CommandType = CommandType.Text;
        String s = oc.ExecuteScalar().ToString();
        return s;
    }
}
catch (OracleException ex)
{
    // either do something meaningful here, or fail hard
    MessageBox.Show(ex.Message);
    throw;
}

正确的方法是将资源获取放置在using-块中:

try
{
    // omit the OracleConnection using if you receive it from elsewhere
    using (OracleConnection con = new OracleConnection(...))
    using (OracleCommand oc = new OracleCommand(query, con))
    {
        oc.CommandType = CommandType.Text;
        // nothing was going to be thrown with just 'return s'
        return oc.ExecuteScalar().ToString();
    }
}
catch (OracleException ex)
{
    MessageBox.Show(ex.Message);
}
return string.Empty;

任何可能失败的语句都应该在try块中,并且肯定包括数据库连接。把这些东西放在哪里的决定与资源分配和处置无关。

只要实现IDisposable的任何对象都得到了适当的处理,那么您就完成了您的工作。这可以通过带有try/finaly块的显式语法:

OracleConnection con;
try {
    con = new OracleConnection();
    // Do stuff here.
} catch {
    // Handle errors here.
} finally {
    if (con != null)
        con.Dispose();
}

或者using语句:

using (var con = new OracleConnection()) {
    // Do stuff here.
}

using语句被转换为try/finaly块。然而,如果你想要一个catch块,你需要回到第一种风格,或者在你的使用中放入一个内部的try/catch块,这可能会带来更多的开销,但在大多数情况下都不会引起注意。

这是一些有能力的人吗?

您在delphi中这样做的原因与在c#中这样做相同。

如果创建一个oracle-comnman实例并抛出异常,那么您的finally将执行并抛出另一个,因为您的实例为null,或者更糟的是,它仍然是垃圾。

这一切都与这样使用有关,除非你正在这样做,你不需要关闭和处理。如果您有DoSomethingElse();在那里,托管和非托管注意事项进入bin。

不,在这种情况下只需要一个try/catch就足够了,比如:

 try
   {
        OracleCommand oc = new OracleCommand(query, con);
        oc.CommandType = CommandType.Text;
        return  oc.ExecuteScalar().ToString();
    }
    catch (OracleException ex)
    {
        MessageBox.Show(ex.Message);
        return string.Empty;
    }
    }
    finally
    {
      con.Close();
      con.Dispose();
    }