我正在检查VB.NET中变量声明的位置无关紧要,除了范围,(对于this question)我认为我更好地检查当它们被“提升”到一个状态时会发生什么关闭。我没有阅读规范,但我无法解释这些结果:
Dim outer As Integer
For i = 1 To 2
Dim inner As Integer
Try
Dim inner2 As Integer
Do
Dim inner3 As Integer
Call Sub()
Dim inner4 As Integer
Console.WriteLine(outer & ", " & inner & ", " & inner2 & ", " & inner3 & ", " & inner4)
outer = i
inner = i
inner2 = i
inner3 = i
inner4 = i
End Sub()
Loop Until True
Finally
End Try
Next
以上输出:
0, 0, 0, 0, 0
1, 1, 0, 1, 0
inner4
每次重置都有意义,其他innerX
全部或全部都没有,但为什么只有inner2
?!
答案 0 :(得分:2)
来自MSDN(强调我的):
[...]编译器基本上做什么,当它进入包含提升变量的新范围时,编译器将检查是否已存在闭包实例;如果是这样,编译器将创建一个新的闭包实例,并重置前一个闭包的变量值。
请注意,如果编译器在生成闭包的函数中检测到循环或GoTo ,则编译器仅执行上述检查 。
答案 1 :(得分:2)
(这是一个评论,但需要太多代码才能保持一致。)
Reflector会显示正在发生什么:
<STAThread> _
Public Shared Sub Main()
Dim e$__ As New _Closure$__1
Try
Dim e$__2 As New _Closure$__2
Dim e$__3 As New _Closure$__3
e$__3.$VB$Local_i = 1
Do
Dim e$__4 As _Closure$__4
e$__4 = New _Closure$__4(e$__4)
Try
Dim e$__5 As New _Closure$__5
Do
Dim e$__6 As _Closure$__6
e$__6 = New _Closure$__6(e$__6)
e$__6.$VB$NonLocal_$VB$Closure_ClosureVariable_8_5 = e$__5
e$__6.$VB$NonLocal_$VB$Closure_ClosureVariable_6_4 = e$__4
e$__6.$VB$NonLocal_$VB$Closure_ClosureVariable_6_6 = e$__3
e$__6.$VB$NonLocal_$VB$Closure_ClosureVariable_4_4 = e$__2
e$__6.$VB$NonLocal_$VB$Closure_ClosureVariable_2_B = e$__
Dim e_ As VB$AnonymousDelegate_0 = New VB$AnonymousDelegate_0(AddressOf e$__6._Lambda$__1)
e_.Invoke
Loop While (0 <> 0)
End Try
e$__3.$VB$Local_i += 1
Loop While (e$__3.$VB$Local_i <= 2)
End Try
End Sub
(这是基于我的代码,其中包含Try
之外的For
。)
你可以在这里看到For
循环(看作Do
循环,之前设置了$VB$Local_i
)和内部Do
生成具有前一个实例的闭包传递的关闭,但Try
没有得到这种处理。
仍然不知道为什么?对我来说看起来像个错误。如果我在一天左右没有得到合理的“借口”(:-)),我会把它放在Connect上。 (有人可以确认.NET 4.5 VB11执行相同的操作吗?)