{"id":5673,"date":"2007-07-26T12:42:00","date_gmt":"2007-07-26T12:42:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/07\/26\/closures-in-vb-part-5-looping\/"},"modified":"2024-07-05T14:42:52","modified_gmt":"2024-07-05T21:42:52","slug":"closures-in-vb-part-5-looping","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/closures-in-vb-part-5-looping\/","title":{"rendered":"Closures in VB Part 5: Looping"},"content":{"rendered":"<p>For previous articles in the series please see<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/05\/02\/closures-in-vb-part-1.aspx\">Part 1: Introduction<\/a>\n<li><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/05\/03\/closures-in-vb-part-2-method-calls.aspx\">Part 2: Method Calls<\/a>\n<li><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/05\/25\/closures-in-vb-part-3-scope.aspx\">Part 3: Scope<\/a>\n<li><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/06\/15\/closures-in-vb-part-4-variable-lifetime.aspx\">Part 4: Variable Lifetime<\/a><\/li>\n<\/ul>\n<p>Once again sorry for the long delay between posts.&nbsp;<\/p>\n<p>Looping structures can cause unintended consequences when used with Lambda expressions.&nbsp; The problem occurs because lambda expressions do not execute when they are constructed but rather when they are invoked.&nbsp; For example take the following code.&nbsp; <\/p>\n<pre>    <span>Sub<\/span> LoopExample1()\n        <span>Dim<\/span> list <span>As<\/span> <span>New<\/span> List(Of Func(Of <span>Integer<\/span>))\n        <span>For<\/span> i = <span>0<\/span> <span>To<\/span> <span>3<\/span>\n            list.Add(<span>Function<\/span>() i)\n        <span>Next<\/span>\n        <span>For<\/span> <span>Each<\/span> cur <span>In<\/span> list\n            Console.Write(<span>\"{0} \"<\/span>, cur())\n        <span>Next<\/span>\n    <span>End<\/span> <span>Sub<\/span><\/pre>\n<p>Many users are surprised to find out the above will print &#8220;4 4 4 4 &#8220;.&nbsp; The reason goes back to my previous 2 posts on variable lifetime and scope.&nbsp; All &#8220;For&#8221; and &#8220;For Each&#8221; blocks in Vb have 2 scopes.&nbsp; <\/p>\n<ol>\n<li>Scope where iteration variables are defined\n<li>Body of the for loop<\/li>\n<\/ol>\n<p>The first scope is entered only once no matter how many times the loop is executed.&nbsp; The second is entered once per iteration of the loop.&nbsp; Any iteration variables that are defined in a For\/For Each loop are created in the first scope (in this case &#8220;i&#8221; and &#8220;cur&#8221;).&nbsp; Hence there is only one of those variables for every loop iteration and the lambda function lifts the single variable &#8220;i&#8221;.&nbsp; <\/p>\n<p>This has thrown off many users because the behavior works most of the time.&nbsp; For instance if I switched the code to run &#8220;Console.Write&#8221; inside the first loop, it would print out&nbsp;&#8220;0 1 2 3 &#8221;&nbsp;as expected.&nbsp; <\/p>\n<p>To mitigate against this problem the above code will actually produce a warning in VB.&nbsp; <\/p>\n<blockquote>\n<p>warning BC42324: Using the iteration variable in a lambda expression may have unexpected results.&nbsp; Instead, create a local variable within the loop and assign it the value of the iteration variable.<\/p>\n<\/blockquote>\n<p>There are two ways to fix this problem depending on the behavior you want.&nbsp; If you see this warning and don&#8217;t know if it affects you, the safest change is to do the following.&nbsp; <\/p>\n<pre>    <span>Sub<\/span> LoopExample2()\n        <span>Dim<\/span> list <span>As<\/span> <span>New<\/span> List(Of Func(Of <span>Integer<\/span>))\n        <span>For<\/span> iTemp = <span>0<\/span> <span>To<\/span> <span>3<\/span>\n            <span>Dim<\/span> i = iTemp\n            list.Add(<span>Function<\/span>() i)\n        <span>Next<\/span>\n        <span>For<\/span> <span>Each<\/span> cur <span>In<\/span> list\n            Console.Write(<span>\"{0} \"<\/span>, cur())\n        <span>Next<\/span>\n    <span>End<\/span> <span>Sub<\/span><\/pre>\n<p>This will cause &#8220;i&#8221; to be created in the second scope.&nbsp; Hence there will be a different value for every loop iteration and the code will print out&nbsp;&#8220;0 1 2 3&#8221;&nbsp;as expected.&nbsp; <\/p>\n<p>If you do want the code to print out &#8220;4 4 4 4 &#8221; then add &#8220;Dim i = 0&#8221; before the start of the loop.&nbsp; <\/p>\n<p>Jared Parsons(<a href=\"http:\/\/blogs.msdn.com\/jaredpar\">http:\/\/blogs.msdn.com\/jaredpar<\/a>)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For previous articles in the series please see Part 1: Introduction Part 2: Method Calls Part 3: Scope Part 4: Variable Lifetime Once again sorry for the long delay between posts.&nbsp; Looping structures can cause unintended consequences when used with Lambda expressions.&nbsp; The problem occurs because lambda expressions do not execute when they are constructed [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[192,195],"tags":[78,117],"class_list":["post-5673","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-jared-parsons","tag-orcas"],"acf":[],"blog_post_summary":"<p>For previous articles in the series please see Part 1: Introduction Part 2: Method Calls Part 3: Scope Part 4: Variable Lifetime Once again sorry for the long delay between posts.&nbsp; Looping structures can cause unintended consequences when used with Lambda expressions.&nbsp; The problem occurs because lambda expressions do not execute when they are constructed [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5673","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=5673"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5673\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=5673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=5673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=5673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}