使用语句和延迟初始化属性时出错
下面的代码将抛出 InvalidOperationException:ConnectionString 属性尚未初始化。在 Load 方法中调用 Connection.Open() 的行引发异常。如果我使用 try-finally 语句而不是 using 语句,则一切正常。谁能解释一下为什么 using 语句会出现异常?
Public Class SomeEntity
Private _Connection As SqlClient.SqlConnection
Private _ConnectionString As String
Protected ReadOnly Property Connection() As SqlClient.SqlConnection
Get
If _Connection Is Nothing Then
_Connection = New SqlClient.SqlConnection(_ConnectionString)
End If
Return _Connection
End Get
End Property
Public Sub New(ByVal connectionString As String)
_ConnectionString = connectionString
End Sub
Public Sub Load(ByVal key As Integer)
Using Connection
Connection.Open()
...
End Using
End Sub
End Class
The code below will throw an InvalidOperationException: The ConnectionString property has not been initialized. The exception is thrown at the line calling Connection.Open() in the Load method. If I use the try-finally statement instead of the using statement, everything works correctly. Can anyone explain why the exception occurs with the using statement?
Public Class SomeEntity
Private _Connection As SqlClient.SqlConnection
Private _ConnectionString As String
Protected ReadOnly Property Connection() As SqlClient.SqlConnection
Get
If _Connection Is Nothing Then
_Connection = New SqlClient.SqlConnection(_ConnectionString)
End If
Return _Connection
End Get
End Property
Public Sub New(ByVal connectionString As String)
_ConnectionString = connectionString
End Sub
Public Sub Load(ByVal key As Integer)
Using Connection
Connection.Open()
...
End Using
End Sub
End Class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有提到一条关键信息:第一次调用 Load() 时它会成功,但此后永远失败。
使用Using时,当Using块退出时,对使用的变量调用Dispose()。因此,在您的场景中:
此时,SqlConnection对象仍然存在,并且仍然由_Connection指向。但它不再处于可用状态,因为它已被 Dispose()d 处理。当第二次调用 Load() 时:
您正在混合冲突的连接管理方法。将连接对象保留为类的成员意味着您希望在 SomeEntity 对象的生命周期内保持连接处于活动状态,但使用Using意味着您希望在每次使用时动态创建和销毁连接。
You failed to mention a key piece of information: It succeeds the first time Load() is called, but then fails forever after.
When using Using, Dispose() is called on the used variable when the Using block exits. So in your scenario:
At this point, the SqlConnection object still exists, and is still pointed to by _Connection. It's no longer in a usable state though, since it's been Dispose()d. When the second call to Load() comes in:
You're mixing conflicting approaches to connection management. Keeping the connection object around as a member of the class implies that you want to keep the connection alive for the life of the SomeEntity object, but using Using implies that you want to create and destroy the connection on the fly with each usage.
Using
语句中的Connection
未初始化或声明。您的代码应该更像:Connection
in yourUsing
statement is not being initialized or declared. Your code should read more like: