[英]C# IDisposable Using: Best Practice
我已经在USING语句中包装我的OracleConnection和OracleCommand对象一段时间了,但是,在运行代码分析器之后,我发现OracleParameter也实现了IDisposable。 以下代码是否正确? 是否有更好的可读性或结构技术? 乍一看,它似乎与USING语句混杂在一起:
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...
}
}
}
您只想在使用的最后处置参数,包括在查询期间(以及可能读取结果):
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...
}
}
}
}
请注意,您可以在一行中放置多个using
语句。 这是因为,就像if
语句一样,
using
语句被认为是一个简单的语句(即使是一个块); 和 using
语句可以使用块或下面的语句。 我不确定它是否能正常工作。 考虑到在使用结束时,两个参数都应该被处理掉。 您的cmd.Parameters
对象仍然保留对它们的引用这一事实并不排除OracleParameter
Dispose方法中可能发生的情况。 对于所有密集目的,该特定对象的开发人员可能正在清除OracleCommand
期望填充的字段。
那里有一些危险。 如果您确定要正确处理OracleParameters
,我建议您在使用OracleDataReader
之后将其丢弃。
请记住,通常在使用完对象后调用Dispose
。 你告诉它释放它所持有的所有资源。 如果您没有使用物体,请不要过早丢弃它。
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...
}
}
不这是不正确的,因为您甚至在使用它们之前就已经处理了这些参数。
相反,你应该这样
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();
你能看一下连接和命令源代码,它是否处理参数? 如果连接或命令对象配置模式包装参数并将它们放置在它们被丢弃的位置。 你应该担心它。 我认为它应该/应该。
此代码不正确。 您创建的params仍然在using
语句范围之外using
因为您将它们添加到参数集合中,但using
语句将在控制离开范围时调用Dispose
参数。 这意味着当时间到了使用命令中的参数时,它们已经被已经去掉了
根据MSDN ,你只需要使用using
的Connection
和DataReader
对象。 我从未见过using
(或.Dispose()
)与ADO.NET参数对象一起使用。 如果这是必要的,甚至是可取的,我认为在过去十年中已经有一段时间了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.