Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it 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. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  6. 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,747
    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?