Это поведение "По замыслу" и является результатом часто неправильно понятой детали оператора With
.
Оператор With
фактически принимает выражение в качестве аргумента, а не прямую ссылку (хотя это один из самых распространенных вариантов использования). Раздел 10.3 спецификации языка гарантирует, что выражение, переданное в блок With
, вычисляется только один раз и доступно для выполнения оператора With
.
Это реализовано с использованием временного. Таким образом, при выполнении выражения .Member
в выражении With
вы обращаетесь не к исходному значению, а к временному, который указывает на исходное значение. Это позволяет для других забавных сценариев, таких как следующие.
Dim o as New Foo
o.bar = "some value"
With o
o = Nothing
Console.WriteLine(.bar) ' Prints "some value"
End With
Это работает, потому что внутри оператора With
вы работаете не с o
, а с временным указанием на исходное выражение. Это временное действие гарантированно будет действительным только в течение жизни оператора With
и, следовательно, в конце будет Nothing
d.
В вашем примере замыкание правильно фиксирует временное значение. Следовательно, когда он выполняется после завершения оператора With
, временное значение равно Nothing
, и код соответствующим образом завершается с ошибкой.