- Home /
 
Can I get a reference (not a copy) to a string from a script?
I'm trying to build a dictionary that contains a reference to a string from a script, such that if the string's value changes, so does the dictionary entry's value changes. I think I'm getting a copy somewhere along the line, and I'm not sure where.
 public class StringTest : MonoBehaviour
 {
     public string TheString = "old value";
 
     void Start()
     {
 
     }
 
     private void OnGUI()
     {
             if (GUI.Button(new Rect(200, 200, 200, 200), "Click string"))
             {
                 TheString = "Changed";
             }
     }
 
     void Update()
     {
 
     }
 }
 
 // in a test script
 Dictionary<string, string> parameters = new Dictionary<string, string>();
 parameters.Add("test_val", GameObject.Find("ValueHolder").GetComponent<StringTest>().TheString);
 
 private void Update()
 {
     if (parameters != null && parameters.Count > 0)
     {
         Utility.Log(parameters.First().Key + "-" + parameters.First().Value);
     }
 }
 
               After I hit the button, TheString's value has changed (I can see it in the inspector), but the test script still prints "test_val - oldvalue".
Where is the copy taking place here, and how can I avoid it?
Answer by Bunny83 · Jul 23, 2013 at 04:18 PM
That's not possible because even a string by itself is actually a reference type but it's treated like a value type since it's an immutable type. So everytime you change a string you will get a new string which will be created somewhere else in memory.
So even when you have a reference to a string, you can never change the string. A string, once created, can never be changed again. See this SO question for more insight: http://stackoverflow.com/questions/10792603/how-are-strings-passed-in-net
What you can do is storing a class in your dictionary which has a string variable. The reference to the class instance can be passed around and you can "change" the string of that class instance (actually you're replacing the string with a new one).
In your case you can declare your Dictionary like this:
     Dictionary<string, StringTest> parameters /*...*/;
 
               then do this:
     parameters.Add("test_val", GameObject.Find("ValueHolder").GetComponent<StringTest>());
 
               In your Update loop you can use:
     parameters.First().Value.TheString
 
              Answer by BimSekai · Jul 23, 2013 at 03:42 PM
Have you tried the C# "ref" keyword ?
 Dictionnary <ref string , ref string>
 
               (I can't test it, unfortunately...)
If you mean parameters.Add("test_valu", ref gameObject..."), then yes. It doesn't compile.
Two differents step, both in the declaration and in the Add.
 Dictionary<ref string, ref string> parameters = new Dictionary<ref string, ref string>();
 parameters.Add("test_val", ref GameObject.Find("ValueHolder").GetComponent<StringTest>().TheString);
                 Your answer
 
             Follow this Question
Related Questions
(Yet another) Accessing array in another script - ref or copy? 1 Answer
Reference script on Behaviour is Missing, but IT'S NOT MISSING 0 Answers
Help on a Power-Up Sequence 1 Answer
Getting UnassignedReferenceException even though reference assigned 1 Answer
What's the best way to store a reference to a script asset? 2 Answers