VB.. NET upcast ByRef的行为类似于ByVal



我遇到了一个奇怪的情况。下面的代码失败了,因为被处置的对象仍然试图被调用子访问,即使被调用的子已经将传入的参数设置为一个新值。

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代码有很多隐式转换

相关内容

  • 没有找到相关文章

最新更新