“尝试”应该在资源分配之前还是之后?

时间:2012-03-26 20:58:00

标签: c# .net try-catch

在德尔福世界中,至少有人认为将资源分配后的尝试放在首位,例如:

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();
}

6 个答案:

答案 0 :(得分:5)

有一个更好的解决方案: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

答案 1 :(得分:3)

在你的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;
}

答案 2 :(得分:3)

正确的方法是将资源获取放在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;

答案 3 :(得分:1)

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

只要适当地处理了实现IDisposable的任何对象,那么您就完成了自己的工作。这是通过带有try / finally块的显式语法:

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 / finally块。但是,如果你想要一个catch块,你需要回退到第一个样式或者在你的使用中放置一个内部的try / catch块,这可能是更多的开销,但在大多数情况下是不可察觉的。

答案 4 :(得分:1)

这有些人是否有能力?

你在delphi中这样做的原因和你在c#中做的一样。

如果创建一个oracle comnmand实例会引发异常,那么你的finally会执行并抛出另一个,因为你的实例是null,或者更糟的是垃圾。

Naff与使用本身有关,除非你这样做,否则你不需要关闭和处置。如果你有DoSomethingElse();在那里,托管和非托管考虑进入垃圾箱。

答案 5 :(得分:0)

不,在这种情况下就足够只有一个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();
    }