Search Unity

Passing int parameters to delegate function becomes reference passing

Discussion in 'Scripting' started by LucianoLin, Sep 15, 2018.

  1. LucianoLin

    LucianoLin

    Joined:
    Nov 29, 2017
    Posts:
    7
    I bind three delegate functions with parameter 0,1,2 to three buttons. Since int is value type, so i think the output should be 0,1,2. But it's not. The output is 3,3,3. It means they are referenced to the same i, which becomes 3 at last.

    Can somebody tells me why it happens?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class TestScript : MonoBehaviour {
    7.  
    8.     public Button[] buttons;
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.         for(int i=0; i < 3; i++){
    13.             int index = new int();
    14.             index = i;
    15.             buttons[i].onClick.AddListener(delegate { OnSelect(index); });
    16.         }
    17.     }
    18.    
    19.     // Update is called once per frame
    20.     void Update () {
    21.        
    22.     }
    23.  
    24.     private void OnSelect(int index=0){
    25.         Debug.Log(index);
    26.     }
    27. }
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Anonymous delegates capture the entire context of their local function call. Try calling something like...
    Code (csharp):
    1.  
    2. void AddListener(Button button, int parameter)
    3. {
    4.    button.onClick.AddListener(delegate { OnSelect(parameter);  });
    5. }
    6.  
    ... in your loop as a workaround. That should create a different local context.

    Honestly, I would just move away from anonymous delegates entirely and create your logic in a different way. They're very tricky to control the lifetime and context of, and are hard to debug.
     
    NRebel likes this.
  3. LucianoLin

    LucianoLin

    Joined:
    Nov 29, 2017
    Posts:
    7
    You are right. Thanks for your help.

    Actually i do in this way because i have multiple buttons which should have similar onclick event, just with different parameters(like the one show before). Is there any better way to realize this functionalities?