Reputation: 155
Note: This applies to both List and ArrayList
Take a look at the following simple code:
class Creature
{
public string Name;
}
class Game
{
// This is a reference type
public Creature CurrentCreature;
}
class Program
{
static void Main(string[] args)
{
// First, we'll create 2 objects and let the
// reference type "CurrentCreature" points to one of them
Creature dragon = new Creature();
dragon.Name = "Dragon";
Creature Unicorn = new Creature();
dragon.Name = "Unicorn";
Game game = new Game();
game.CurrentCreature = dragon;
// Now we'll create a list which will contain
// the reference type "CurrentCreature"
List<Creature> list = new List<Creature>();
list.Add(game.CurrentCreature);
foreach (Creature c in list)
{
Console.WriteLine(c.Name); // Output is "Dragon"
}
// Now, we'll let "CurrentCreature" point to a different object
game.CurrentCreature = unicorn;
// The reference in the list still pointing to the original object!!!
foreach (Creature c in list)
{
Console.WriteLine(c.Name); // Output is "Dragon"!!!
}
Console.ReadLine();
}
}
I checked how a list adds an item and there is no instantiation of a new object. This is List.Add method (using Reflector tool)
public void Add(T item)
{
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
this._items[this._size++] = item; // No instantiation
this._version++;
}
So, why is this happenning? The element in the list should be a reference to the object pointed to by "CurrentCreature" or is it not? Isn't it similar to the following code if we remove the list?:
class A
{
public B X;
}
class B
{
public string Name;
}
....
A a = new A();
B b1 = new B(); b1.Name = "b1";
B b2 = new B(); b2.Name = "b2";
a.X = b1;
Console.WriteLine(a.X.Name); // output: b1
b1 = b2;
Console.WriteLine(a.X.Name); // output: b1
Upvotes: 0
Views: 344
Reputation: 6683
When you do
game.CurrentCreature = unicorn;
You overwrite the pointer in game.CurrentCreature with one to the unicorn object. The array still has a pointer to the dragon object. It shouldn't be changed, this is how pointers work.
Edit:
A little explanation of what happens with the pointers:
First you created 2 objects
Creature dragon = new Creature();
dragon.Name = "Dragon";
Creature Unicorn = new Creature();
dragon.Name = "Unicorn";
This made dragon have a pointer to your dragon object, and unicorn have a pointer to your unicorn object.
Then you set the pointer of game.CurrentCreature to dragon's pointer.
game.CurrentCreature = dragon;
Then you add a pointer to dragon, the current creature, to the list
List<Creature> list = new List<Creature>();
list.Add(game.CurrentCreature);
Then you replace the pointer in game.CurrentCreature(was dragon) with a pointer to the unicorn object.
game.CurrentCreature = unicorn;
This will in no way affect the pointer held in the dragon object.
Cheers,
Upvotes: 2
Reputation: 4165
Reference is copied to a list, not an object. After list.Add(myobject);
you get two references (that are referring to the same object): myobject and those one that is in a list.
Upvotes: 0
Reputation: 60190
Reference types don't just change.
You're adding the creature to the list, not the game. Then you change the game's reference to use anoter creature; but the creature referenced in the list remains the same, thus it outputs the same result again.
Upvotes: 1