试图理解使用'声明中更好

本文关键字:声明 更好 | 更新日期: 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的实现。