VB.NET Upcasted 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(),因为没有必要。通过使用函数而不是Sub可以避免这种损失:

  Function Foo(ByVal astream as Stream) As MemoryStream
     ''do stuff
     astream.Dispose()
     Return New MemoryStream()
  End Function

尽管这是相当奇怪的代码。

最后但并非最不重要的一点是,您可以让编译器为此发出诊断。项目+属性,编译选项卡,警告配置部分。将“隐式转换”从“无”更改为“警告”。但是,这往往是一个嘈杂的警告,典型的VB.NET代码具有很多隐式转换。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章