C#IDisposable使用:最佳实践
我已经在USING语句中包装了我的OracleConnection和OracleCommand对象一段时间了,但是,在运行代码分析器之后,我发现OracleParameter还实现了IDisposable。以下代码正确吗?是否有更好的可读性或结构技术?乍一看,它似乎被使用语句弄得乱七八糟:C#IDisposable使用:最佳实践,c#,coding-style,idisposable,using,C#,Coding Style,Idisposable,Using,我已经在USING语句中包装了我的OracleConnection和OracleCommand对象一段时间了,但是,在运行代码分析器之后,我发现OracleParameter还实现了IDisposable。以下代码正确吗?是否有更好的可读性或结构技术?乍一看,它似乎被使用语句弄得乱七八糟: using (OracleConnection conn = new OracleConnection(connectionstring)) { conn.Open(); using (Ora
using (OracleConnection conn = new OracleConnection(connectionstring))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(sql, conn))
{
cmd.BindByName = true;
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input))
{
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
}
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input))
{
param2.Value = value2;
cmd.Parameters.Add(param2);
}
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
}
我不确定那是否能正常工作。考虑到在使用结束时,两个参数都应该被处理。您的
cmd.Parameters
对象仍保留对它们的引用这一事实并不排除在OracleParameter
Dispose方法中可能发生的情况。出于所有密集目的,该特定对象的开发人员可能正在清除您的OracleCommand
希望填充的字段
那里有些危险。如果您完全确定要正确处理OracleParameters
,我建议您在使用OracleDataReader
后处理它们
请记住,通常在使用完对象后调用
Dispose
。你告诉它释放它保留在池中的所有资源。如果您没有使用完对象,不要过早地处理它。否这是不正确的,因为您甚至在使用参数之前就处理了参数
相反,你应该这样做
OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input);
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
param1.dispose();
param2.dispose();
你能看一下连接和命令的源代码吗?它是否处理了参数?如果连接或命令对象释放模式包装参数,并在释放后进行释放。你应该担心。我认为这是/应该的。您希望仅在参数使用结束时,包括在查询期间(以及可能在读取结果时),才处理这些参数: 请注意,您可以使用语句将多个
放在一行中。这是因为,就像if
语句一样
使用
语句的被认为是一个简单语句(即使有块);及
使用
语句的可以包含块或下面的语句
此代码不正确。您创建的参数仍然在using
语句作用域之外使用,因为您将它们添加到参数集合中,但是using
语句将在控件离开作用域时对参数调用Dispose
。这意味着,当使用命令中的参数时,您只需使用连接和数据读取器对象。我从未见过使用ADO.NET参数对象的(或.Dispose()
)。如果这是必要的,甚至是可取的,我认为它在过去10年中已经出现了。MSDN正在讨论BCL提供的对象。Oracle实现这些功能很可能需要处理这些参数。如果不打算处置它们,它们为什么要实现IDisposable?或者它们很可能不会。我从未见过任何ADO.NET代码(用于Oracle的实现或其他任何人的实现)对参数对象调用Dispose(),或使用
块将其放入。同样,如果需要处理参数,这在很久以前就已经出现了。因此,您的建议是,即使对象实现了IDisposble,除非已知有问题,否则不要处理它?对我来说,这听起来是个糟糕的建议。我可以很容易地选择比“抱歉”更好的安全路线并进行处置,但我真的认为Oracle搞砸了这一点,他们的处置方法可能没有任何意义。虽然有许多类似的答案,但我感谢您提供了示例和注释。谢谢!很高兴我能帮上忙。:-)
using (OracleConnection conn = new OracleConnection(connectionstring))
using (OracleCommand cmd = new OracleCommand(sql, conn))
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32,
System.Data.ParameterDirection.Input))
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2,
System.Data.ParameterDirection.Input))
}
conn.Open();
cmd.BindByName = true;
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
using (OracleConnection conn = new OracleConnection(connectionstring))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(sql, conn))
{
cmd.BindByName = true;
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input))
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input))
{
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
}
}