Subtle differences with closure on loop variables in different programming languages (C## and JavaScript as examples)

Closure is not a new concept. It was first introduced in the 1970s and is now available in most of the programming languages. I am sure most developers are familiar with it and use it on a regular basis. Here are some quick tests to check our understandings — can you tell the output for the four cases below in JavaScript and C#:

TypeScript (plain JavaScript if you ignore the array typing):

const list = [0, 1, 2, 3];
const funcList: (() => number)[] = [];
const funcList2: (() => number)[] = [];

for (let i = 0; i < list.length; i++) {
  funcList.push(() => list[i]);
}
funcList.map(f => console.log(f()));   // case#1
for (var i = 0; i < list.length; i++) {
  funcList2.push(() => list[i]);
}
funcList2.map(f => console.log(f()));  // case#2

C#:

var list = new int[] { 0, 1, 2, 3 };
var funcList = new List<Func<int>>();
var funcList2 = new List<Func<int>>();

foreach (var item in list)
{
    funcList.Add(() => item);
}
funcList.ForEach(f => Console.WriteLine(f()));   // case#3
for (var i = 0; i < list.Length; i++)
{
    funcList2.Add(() => list[i]);
}
funcList2.ForEach(f => Console.WriteLine(f()));  // case#4

At first glance it might seem like we should be getting below for all four cases across these two languages:

0
1
2
3

Here is the actual output:

Case#1: logs above output as expected

Case#2: logs 4 “undefined”

Case#3: prints above output as expected

Case#4: IndexOutOfRangeException

#c-sharp-programming #javascript #closure #c# #c-sharp

Closure on Loop Variables — C# and JavaScript Comparison
1.90 GEEK