Something odd about adding listener to a button

I have a simple setup where I want to add listeners to buttons with parameters so that they open a video in a list. This is the code:

for (int i = 0; i < videoClips.Count; i++) {
	GameObject newBtn = Instantiate(btnPrefab, btnHolder);
	newBtn.GetComponent<Button>().onClick.AddListener(() => { OpenVideo(i); });

	// int k = i;
	// newBtn.GetComponent<Button>().onClick.AddListener(() => { OpenVideo(k); });

	newBtn.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = videoClips[i].name;

Weirdly enough the parameter that I pass into the OpenVideo(int i) always seems to be equal to the length of the videoClips list if I try to pass in i in the AddListener for All the buttons. The commented version where I make a new int k = i work as intended however… I do not understand why this behaviour is happening.

The answer is pretty much related to lambda capture , look it up , but basically the lambda keeps a “reference” to i , even while it’s incrementing and once you call your button , it will call the “last captured value”

Apparently, it has to do with Closing over the loop variable with the lambda function. If curious some details are in the following thread.