Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

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:
    1,674
    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.
     
  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?