我遇到了一个奇怪的情况。下面的代码失败了,因为被处置的对象仍然试图被调用子访问,即使被调用的子已经将传入的参数设置为一个新值。
Sub Foo(ByRef astream as Stream)
'do stuff
astream.Dispose()
astream = New MemoryStream()
End Sub
Sub Other()
Dim memstream as New MemoryStream()
Foo(CType(memstream, Stream))
memstream.Position = 0' <- FAILS with Object Disposed!
End Sub
Sub Foo(ByRef astream as MemoryStream)
'do stuff
astream.Dispose()
astream = New MemoryStream()
End Sub
Sub Other()
Dim memstream as New MemoryStream()
Foo(memstream)
memstream.Position = 0' <- This works now!
End Sub
那么,为什么第一个不工作,当涉及到升级,第二个工作?
编辑:忘了说我在VS 2013中使用的是June Roslyn CTP(以防那里有bug)。
谢谢。
Foo(CType(memstream, Stream))
CType()表达式生成一个临时变量。它会被更新。换句话说,编译器生成如下代码:
Dim $Temp = CType(memstream, Stream)
Foo($Temp)
显然这不会让你的memstream变量更新。您将需要一个命名变量:
Dim temp = CType(memstream, Stream)
Foo(temp)
memstream = temp
或者完全避免使用CType(),因为它是不必要的。可以通过使用Function而不是Sub来避免这种损失:
Function Foo(ByVal astream as Stream) As MemoryStream
''do stuff
astream.Dispose()
Return New MemoryStream()
End Function
虽然这是相当奇怪的代码。
最后但并非最不重要的是,您可以让编译器为此发出诊断。项目+属性,编译选项卡,警告配置部分。将"隐式转换"从None更改为Warning。然而,它往往是一个嘈杂的警告,典型的VB。. NET代码有很多隐式转换