- 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