How to store references to values rather than values themselves (in a dictionary?)

I’m trying to create a dictionary of reference types that I can later use to access their individual current values - however, what happens instead is that I only ever retrieve the cached value at the start, rather than the current one.

Specifically, here is the dictionary:

public Dictionary<string, Stat> tooltips = new Dictionary<string, Stat>()
    {
        { "firstItem", PlayerController.attributes.newStatA },
        { "secondItem", PlayerController.attributes.newStatB },
        { "thirdItem", PlayerController.attributes.newStatC }
    };

And here is the Stat class the references to which I intend to store in the dictionary:

public class Stat
{
    public double value { get; set; }
   
    public Stat (double value)
    {
        this.value = value;
    }
}

The idea is to be able to retrieve the current value - e.g., newStatA.value - by accessing it via the dictionary (for example, Debug.Log(tooltips[firstItem].value) should display the current value of newStatA). Instead, accessing it in this manner retrieves the value of newStatA as it existed when the instance of the class was created - even though newStatA.value updates correctly.

Thoughts? I suspect I went wrong somewhere with value and reference types, but all the tutorials I’ve come across recommend encapsulation of value types to avoid this (which I’ve already done through creating the Stat class).

Best,
George

P.S. For those particularly curious, what I’m really after is to create a reasonably procedural tooltip system - meaning, every attribute, such as player damage, player health, etc, should have a tooltip associated with it accessible via the same string ID as the upgrade affecting that attribute (hence the need for string-based dictionaries).

There is a pretty comprehensive answer here -c# - Store reference to an object in dictionary - Stack Overflow

Hopefully that solves your issue.

If any of that seems complicated or you require further help, don’t hesitate to ask!

1 Like

Thanks! Gonna give it a shot and post here if I can’t figure something out!

That should work as-is, as you’re stuffing reference types in the dictionary . The error’s somewhere else - you’re probably replacing PlayerController, PlayerController.attributes, or PlayerController.attributes.newStatA. Here’s a test script:

using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour {

    void Start() {
        Stat a = new Stat(15);
        Stat b = new Stat(15);
        Stat c = new Stat(15);

        Dictionary<string, Stat> dict = new Dictionary<string, Stat>()
        {
            { "a", a },
            { "b", b },
            { "c", c }
        };

        a.value = 1;
        b.value = 2;
        c.value = 3;

        Debug.Log("a: " + dict["a"].value); //prints 1
        Debug.Log("b: " + dict["b"].value); //prints 2
        Debug.Log("c: " + dict["c"].value); //prints 3
    }

    public class Stat
    {
        public double value { get; set; }
   
        public Stat (double value)
        {
            this.value = value;
        }
    }
}
1 Like

Thanks! It compiled and worked exactly as you said it would, which means the error must be somewhere on my end and not in the way the dictionary is managed.

Will keep digging!