Could someone please explain the behavior of this
class testCompile
{
/*
* Sample Code For Purpose of Illustration
*/
struct person
{
public int age;
public string name;
}
static void Main(string[] args)
{
List<person> Listperson = new List<person>();
person myperson = new person();
for (int i = 1; i <= 2; i++)
{
//Assignment
myperson.age = 22+i;
myperson.name = "Person - " + i.ToString();
Listperson.Add(myperson);
}
int x = 0;
while (x < Listperson.Count)
{
//Output values
Console.WriteLine("{0} - {1}", Listperson[x].name, Listperson[x].age);
x++;
}
}
}
/*
Output:
Person - 1 - 23
Person - 2 - 24
*/
Why am I not getting the same output for a class as that of a struct?
class testCompile
{
/*
* Sample Code For Purpose of Illustration
*/
class person
{
public int age;
public string name;
}
static void Main(string[] args)
{
List<person> Listperson = new List<person>();
person myperson = new person();
for (int i = 1; i <= 2; i++)
{
//Assignment
myperson.age = 22+i;
myperson.name = "Person - " + i.ToString();
Listperson.Add(myperson);
}
int x = 0;
while (x < Listperson.Count)
{
//Output values
Console.WriteLine("{0} - {1}", Listperson[x].name, Listperson[x].age);
x++;
}
}
}
/*
Output:
Person - 2 - 24
Person - 2 - 24
*/
Because your myperson variable only ever deals with one person struct/class.
What you add to the list, in your loop, is a copy of your myperson variable - which for the struct, will be an entire copy of the struct, but for the class will be a copy of the reference to the single instance that you create (and mutate).
Classes are reference types, structs are value types.
When a value type is passed to a method as a parameter, a copy of it will be passed through. That means that you add two completely separate copies of the
Person
struct, one for each pass in the loop.When a reference type is passed to a method as a parameter, the reference will be passed through. That mean that you add two copies of the reference to the same memory location (to the same
Person
object) - when making changes to this one object, you see it reflected in both references since they both reference the same object.In the second instance, you're addding a reference type. In fact, you're adding the same item, twice, since your
is not in the loop. So it always points to the same object you initialized here:
Even after it's added to your list, the changes affect it.
In the first instance, you're adding a struct each time, which is a value type, so will be copied into the list. Changes you make after that no longer refer to the object in the list, so they have different values.
In the second example you're only creating on item and adding a reference to to the list many times.