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

时间:2014-07-21 15:16:24

标签: vb.net casting byref

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

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

那么,为什么第一个在涉及向上转换时不起作用,第二个有效呢?

编辑:忘记提及我正在使用June Roslyn CTP for VS 2013(如果它是一个bug)。

感谢。

1 个答案:

答案 0 :(得分:2)

  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

虽然这是相当奇怪的代码。

最后但并非最不重要的是,您可以让编译器为此发出诊断信息。项目+属性,编译选项卡,警告配置部分。改变&#34;隐含转换&#34;从无到警告。然而,它往往是一个嘈杂的警告,典型的VB.NET代码有很多隐式转换。