2

我今天遇到了一个关于 lambda 函数闭包和 VBWith语句的交互的非常有趣的怪癖。这是一个简短的代码片段来演示这个问题(我试图让它尽可能地小),然后是我认为问题所在的概述:

Module Module1
    Sub Main()
        Dim someList = New List(Of String),
            myInvoker As Invoker

        With someList
            Dim listFiller = Sub()
                                 .Add("Hello") '<- This is where the problem is
                             End Sub

            myInvoker = New Invoker(listFiller)
        End With

        myInvoker.Invoke()
        Console.WriteLine(String.Join(",", someList))
        Console.ReadKey()
    End Sub
End Module

'This is just an object that accepts a delegate and invokes it when told to
Public Class Invoker
    Public Delegate Sub ArbitraryDelegate()
    Private _ArbitraryCallBack As ArbitraryDelegate

    Public Sub Invoke()
        _ArbitraryCallBack.Invoke()
    End Sub

    Public Sub New(arbitraryCallback As ArbitraryDelegate)
        _ArbitraryCallBack = arbitraryCallback
    End Sub
End Class

基本上,我正在创建一个引用类型的实例(List(Of String)在这种情况下是 a,但它可以是任何东西),将它存储在一个变量中,然后在With语句中使用它。当我创建一个 lambda 函数来访问这个对象的方法时,问题就出现了.Add。一旦我创建了 lambda 函数,我将它传递给某个外部对象,以便稍后调用。

不幸的是,当外部对象试图调用给定的 lambda 函数时,它会遇到System.NullReferenceException,因为 lambda 表达式(无论出于何种原因)未能关闭subList。如果我明确写subList.Add("Hello"),它会再次起作用。据我所知,这两种情况的行为应该相同,因为以.Add.

我的问题是,这是否是 With 语句实现方式的错误,或者我是否遗漏了某些东西,这是预期的行为。

4

0 回答 0