如果“;尝试“;在资源分配之前或之后
本文关键字:或之后 尝试 如果 资源分配 | 更新日期: 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();
}