代码之家  ›  专栏  ›  技术社区  ›  csauve

vb.net-“with”和闭包不混合

  •  7
  • csauve  · 技术社区  · 14 年前

    我想我会分享这个以防其他人碰到这个。
    我今天做了类似的事情,花了一段时间才弄明白为什么这会在运行时引起问题。

    此代码:

    Public Class foo
      Public bar As String = "blah"
    End Class
    
    Public Sub DoInline()
      Dim o As New foo
      Dim f As Func(Of String)
      With o
        f = Function() .bar
      End With
      Try
        Console.WriteLine(f.DynamicInvoke())
      Catch ex As Reflection.TargetInvocationException
        Console.WriteLine(ex.InnerException.ToString)
      End Try
    End Sub
    

    引发NullReferenceException。似乎with使用闭包作为临时存储,在“end with”中,它将闭包的变量设置为Nothing。

    这是红门反射镜的代码:

    Public Shared Sub DoInline()
        Dim o As New foo
        Dim $VB$Closure_ClosureVariable_7A_6 As New _Closure$__1
        $VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = o
        Dim f As Func(Of String) = New Func(Of String)(AddressOf $VB$Closure_ClosureVariable_7A_6._Lambda$__1)
        $VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = Nothing 
        Try 
            Console.WriteLine(RuntimeHelpers.GetObjectValue(f.DynamicInvoke(New Object(0  - 1) {})))
        Catch exception1 As TargetInvocationException
            ProjectData.SetProjectError(exception1)
            Console.WriteLine(exception1.InnerException.ToString)
            ProjectData.ClearProjectError
        End Try
    End Sub
    

    注意到

    $VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = Nothing 
    

    我真正能问的唯一“问题”是:这是一个bug还是一个奇怪的设计决策,出于某种原因我看不到。 从现在开始,我基本上是要避免使用“with”。

    2 回复  |  直到 14 年前
        1
  •  8
  •   JaredPar    14 年前

    With

    .Member

    Dim o as New Foo
    o.bar = "some value"
    With o   
      o = Nothing
      Console.WriteLine(.bar) ' Prints "some value"
    End With
    

    o Nothing

        2
  •  1
  •   Hans Passant    14 年前