I'm writing an interpreter in c#. For variables I have a system where I have a class representing a variable:
class var { public Hashtable Children; public object Value; } |
When a variable is declared, I do something like this:
var Temp = new var(); Temp.Value = something; VarIndex.Add("variable name",Temp); |
However I've found adding the Temp object to the hashtable just adds a reference to the object - if I then use the same Temp object to store another variable in the hashtable, the first variable inherits these characteristics.
Is there any way to get the hashtable to store the whole object, not just a reference

Objects stored in a hashtable - by reference?
Raphael39913
void Add(var ToAdd)
{
var Temp = new var();
Temp = ToAdd;
hash.Add("key", Temp);
}
You create a local variable named Temp, create a new instance, and assign temp to point to that instance. You then point Temp to the same instance as the ToAdd parameter points to. (The var you created on the first line using "new var()" is no longer reachable and will be collected the next time the garbage collector runs.) You then add the object pointed to by Temp to the hashtable. This code will behave identically to:
void Add(var ToAdd)
{
hash.Add("key", ToAdd);
}
What you really want to do is:
void Add(var ToAdd)
{
var Temp = new var();
Temp.Value = ToAdd.Value;
hash.Add("key", Temp);
}
Note that Temp, ToAdd, and the hashtable all point to the same object contained in value. If you want to do a deep copy, you'll have to duplicate whatever is in Value.
You might want to consider implementing the ICloneable interface on your var class. It's a more generic way to create duplicates of your objects than hand-copying properties whenever you need to duplicate the object. Then you could write:
void Add(var ToAdd)
{
hash.Add("key", ToAdd.Clone());
}
SavageE
Thanks alot. it's as I thought, you need a separate object for each entry.
I've been told that if I did something like this
void Add(var ToAdd)
{
var Temp = new var();
Temp = ToAdd;
hash.Add("key", Temp);
}
would work ok as even though the object Temp goes out of scope at the end, garbage collection doesn't destroy it as it's being referenced. This is fine for what I need, I'll be using functions for all storing. The example where I used the same object for several was actually just for testing!
Thanks alot
Jim Crayne
The var is a class and not a primitive. You will need to create a clone of the object and put that in the hashtable instead of the object itself.
SmoothUK
When you implement IClonable, make sure to pay attention to which member variables are value types and reference types.
Below is a sample Clone implementation that does a deep copy of enclosed reference types. String is a special reference type that does not need to be specially dealt with since it's immutable -- any change to the string returns a new string, so it's okay if they both point to the same place.
class Foo : ICloneable
{
Foo[] _arrayofFoos;
int _i;
string _myStr;
public object Clone()
{
// this only does a shallow-copy -- value types will be copied
// for reference types, the reference is copied -- i.e., they'll
// both point to the same object. _arrayofFoos will be the same
Foo f = this.MemberwiseClone();
// make a copy of the array and all of its children
Foo[] newArr = new Foo[_arrayofFoos.Length];
for(int i = 0; i < _newArr.Length; i++)
{
newArr[ i ] = _arrayofFoos[ i ].Clone();
}
f._arrayofFoos = newArr;
return f;
}
}
Christopher Fleming
-Shawn