0

I have the following, which runs at the initialization of a node graph system for every ports of a node;

    private void Initialize()
    {
        // stats.Length return 3;
        for (int i = 0; i < stats.Length; i++)
            stats[i].Initialize(this, () => GetStats(i));
    }

    private void GetStats(int index)
    {
        // Issue; index returns 3
    }

If I print the i in the for loop, I get 0, 1, 2 as expected when I have 3 items.

Somehow, if I print index in GetStats, I get 3.

I'm just at lost here, how is a value-type parameter in a method nested in a lambda can change value? Am I doing something stupid?

LightStriker
  • 19,738
  • 3
  • 23
  • 27
  • 4
    See here: http://stackoverflow.com/q/12861560/5311735 – Evk Jun 01 '16 at 19:34
  • @Evk That's so counter-intuitive to how value-type behave... – LightStriker Jun 01 '16 at 19:36
  • Suppose you have a class A with integer field B. If you pass A to 100 functions and then change B - all 100 functions will see changed value, even if B is value-type. About the same story is here. – Evk Jun 01 '16 at 19:39
  • @Evk True, but in this case I'm not passing a member, I'm passing a value-type created on the stack. So how are 100 functions referencing a value from the stack that is long gone? Obviously, it has to be boxed in the delegate created. So how is at the moment of the boxing the value-type not being copied? – LightStriker Jun 01 '16 at 19:52
  • It's lifetime is extended, because compiler will rewrite the whole thing about as I described in a comment. So it will generate a class with int member, create instance of that class and your "i" is not on the stack any more - it's a field in that compiler-generated class. That's all because "i" is captured by your lambda and it's lifetime is not restricted by method boundary any more. – Evk Jun 01 '16 at 19:59

0 Answers0