嵌套使用语句有用吗?

问题描述 投票:4回答:5

关于资源密集型操作(例如,打开数据库连接)的最佳实践的共识似乎是使用Using块,因为Using"guarantees disposal of the resource... even in the case of an unhandled exception."

这是我发现的大多数示例的书写方式:

Sub ExecuteCommand(ByVal sql As String, ByVal connectionString As String)
    Using connection As New SqlConnection(connectionString)
        Dim command As New SqlCommand(sql, connection)
        command.Connection.Open()
        command.ExecuteNonQuery()
    End Using
End Sub

但是嵌套的Using块是允许的,我偶尔(但很少)看到上面写为:

Sub ExecuteCommand(ByVal sql As String, ByVal connectionString As String)
    Using connection As New SqlConnection(connectionString)
        Using command As New SqlCommand(sql, connection)
            command.Connection.Open()
            command.ExecuteNonQuery()
        End Using
    End Using
End Sub

我的问题:多个嵌套Using块有什么好处?还是单一的Using块已经保证它包含的所有资源都将被处置?

((注意:我的代码在VB.NET中,但是相同的问题也适用于C#。)

c# vb.net using
5个回答
10
投票
using块“即使在未处理的异常情况下也保证资源的使用...。”>

把那“保证金”和一粒盐一起拿。许多事情都会阻止资源的处置。如果using块包含无限循环怎么办?还是该块引发了异常,堆栈上较高级别的敌对异常过滤器进入了无限循环,并且从未将控制权返回给与using语句关联的finally块?还是该块调用Environment.FailFast?有很多事情可能会阻止废物处置的进行。

切勿编写依赖其正确性处置的程序

politeness可以进行处置,将稀缺的资源返回到池中供其他人使用。此外,让我确保这一点很明确:

真正未处理的异常是C#中实现定义的行为

using块的finally子句用于处理在使用块然后在其他地方处理]中引发异常的情况,而不是处理在块和从不处理。如果发生这种情况,则完全取决于实现来确定发生了什么。 C#语言对引发从未处理的异常的程序的行为做出的承诺总计为零。资源可能会被处置。他们可能不会。您所在的建筑物即将被意外拆除;您是否真的想花时间洗碗并整齐地存放它们?
多个嵌套的Using块有什么好处?

单个Using块是否已经保证它包含的所有资源都将被处置?

没有仅清除using语句实际提及的资源。这就是为什么要嵌套它们。

在某些情况下,从技术上讲您不必这样做,因为内部资源负责释放与外部资源相同的资源。但是,使用块嵌套不会对您造成任何伤害,并且使读者很清楚发生了什么事情。这里的最佳实践是对要清除的每个资源都有一个using语句。

嵌套的using块绝对有用:单个块将仅在其自己的变量上调用Dispose,而不是在同一块内部可能打开的其他变量上调用。这就是为什么要在程序的定义点清除的每个变量(应该是实现IDisposable类型的每个变量)都需要自己的using块。

Using语句将处理在Using行中声明的变量。它对块中其他位置声明的变量没有影响。

您应始终对每个一次性变量使用Using语句。

所有其他答案都是正确的。我还要再加一点。

如果对象是同一类型,则c#编译器提供了一种方法(语法糖),可以在单个using语句内联中使用多个对象。

C#版本

using (MemoryStream ms1 = new MemoryStream(), ms2 = new MemoryStream()) { }

Vb.Net版本

Using ms1 = New MemoryStream(), ms2 = New MemoryStream() End Using

这将同时处理两个MemoryStream

嵌套using语句非常有用。但是,许多程序员并不认为SqlCommand对象需要进行资源清理。也就是说,资源是连接,而不是命令。

已添加

SqlCommand没有Close()方法,因此,即使SqlCommand具有Dispose()方法,缺少Close()方法也表明实际上没有任何东西可以关闭/释放。一次性实例最终将始终被处置。很难找到权威的东西,而无需深入研究源代码,但是当在this article中被问及MS家伙确切地处置了它时,他说“实际上并不多...”,并继续为SqlCommand建议USING子句( ),所以我正确回答了这个问题,但最初避免了它背后的模糊性。


7
投票
嵌套的using块绝对有用:单个块将仅在其自己的变量上调用Dispose,而不是在同一块内部可能打开的其他变量上调用。这就是为什么要在程序的定义点清除的每个变量(应该是实现IDisposable类型的每个变量)都需要自己的using块。

3
投票
Using语句将处理在Using行中声明的变量。它对块中其他位置声明的变量没有影响。

1
投票
所有其他答案都是正确的。我还要再加一点。

1
投票
嵌套using语句非常有用。但是,许多程序员并不认为SqlCommand对象需要进行资源清理。也就是说,资源是连接,而不是命令。
© www.soinside.com 2019 - 2024. All rights reserved.