试图理解使用'声明中更好
本文关键字:声明 更好 | 更新日期: 2023-09-27 18:14:44
我读了几篇关于using语句的文章,试图理解什么时候应该使用它。听起来好像大多数人都认为应该尽可能多地使用它,因为它可以保证处理未使用的对象。
问题是所有的例子总是显示这样的东西:
using (SqlCommand scmFetch = new SqlCommand())
{
// code
}
这是有道理的,但它是如此小的一段代码。在数据库上执行查询时,我应该怎么做?所有的步骤是什么?它会看起来像这样吗?
string sQuery = @"
SELECT [ID], [Description]
FROM [Zones]
ORDER BY [Description] ";
DataTable dtZones = new DataTable("Zones");
using (SqlConnection scnFetchZones = new SqlConnection())
{
scnFetchZones.ConnectionString = __sConnectionString;
scnFetchZones.Open();
using (SqlCommand scmdFetchZones = new SqlCommand())
{
scmdFetchZones.Connection = scnFetchZones;
scmdFetchZones.CommandText = sQuery;
using (SqlDataAdapter sdaFetch = new SqlDataAdapter())
{
sdaFetch.SelectCommand = scmdFetchZones;
sdaFetch.Fill(dtZones);
}
}
if (scnFetchZones.State == ConnectionState.Open)
scnFetchZones.Close();
}
我想知道的是:
•是否可以使用4、5、10个嵌套的using语句来确保所有对象都被处置?
•我做错了什么,我应该考虑修改吗?
•如果由于嵌套的using语句太多,需要修改,我有什么选择?
您最终可能会得到一个令人生畏的层次结构,但是您的代码应该非常高效,对吧?或者,您是否应该只把,例如,SqlDataAdapter
对象放在using语句中,并且它将以某种方式确保所有其他对象也被处理掉?
谢谢。
嵌套多个using语句是完全合法的:
using(A a = new A())
using(B b = new B())
{
a.SomeMethod(b);
}
如果您使用的每个IDisposable都使用using,那么您永远不会出错。
Using语句是c#的语法糖。
所以下面的代码:
using(var someDisposableObject = new someDisposableObject())
{
// Do Something
}
实际上看起来像:
var someDisposableObject = new someDisposableObject();
try
{
// Do Something
}
finally
{
if (someDisposableObject != null)
{
((IDisposable) someDisposableObject).Dispose();
}
}
看这篇文章:http://msdn.microsoft.com/en-us/library/yh598w02.aspx
深度没有限制,所以不用担心。您应该验证using的对象是否实现了IDisposable。被处置的对象不会处置与之相连的所有对象,只处置它所创建的对象。
那么,你在哪里做错了呢?没有限制,但通常它相当肤浅,你创建对象,执行任务,然后对象被处置。如果你做得很深入,我会看一下你的设计。我觉得你很难再多做几层了。
至于重新设计的选项,这实际上取决于您正在做什么,但您可能会将同一个对象用于多个任务。最有可能的是,您最终将任务分解为一个函数(传入所需的任何周围对象)。
•是否可以使用4、5、10个嵌套的using语句来确保所有对象都被处置?
回复:你不能限制使用嵌套的"using block "
•我做错了什么,我应该考虑修改吗?
回复:如果你有很多嵌套的"using block"。
using (var con = new SqlConnection(connStr))
using (var cmd = new SqlCommand(queryStry))
using (var rs = cmd.ExecuteReader())
{
while (rs.Read())
{
//Code.
}
}
就我个人而言,我已经多次使用了至少3层(连接,命令,其他),我认为它绝对没有问题,但正如你已经暗示的那样,最终会出现可读性问题。与其他嵌套结构一样,您可能需要平衡效率和可维护性。也就是说,你不一定需要牺牲效率,但通常有不止一种方法来剥猫的皮。
也就是说,你将很难生成10个嵌套层!
恕我直言,你需要问自己的是:有哪些选择?Try/finally块吗?它们更具可读性吗?更易于维护吗?在几乎所有情况下,答案都是否定的。
所以用using
。这是c#与c++的RAII模式最接近的东西,它都很好:-)
有一次我能想到你不想在连接上使用'using'的地方是在连接对象(如datareader)的ClassFactories上,例如考虑以下情况
private IDataReader CreateReader(string queryString,
string connectionString)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
return command.ExecuteReader(CommandBehavior.CloseConnection);
// Don't close connection
}
(从MSDN修改- MSDN上的例子只是简单的愚蠢)
另一个原因是在WCF ServiceReference 'clients'上——如果通道出现故障,'using'就会隐藏实际的异常。但这只是一个有bug的实现。