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
*/
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.
When you add the struct to the collection, it makes a copy of it. It's a value type. You'll end up with two distinct objects in the collection, each with different values. This is probably the expected behavior.
When you add the class, the reference type, to the collection, a new object is not created. You're actually adding two different references to the same object. You'll end up with (apparently) two objects with the same value. It's actually the same object, seemingly appearing twice in the collection.
Structures are value types and classes are reference types. So in your first example when you add myperson to the list your adding a copy of myperson and the myperson variable still refers to a separate copy. In you second example myperson is a reference type so your adding two pointers to the same object.
If you want same result then bring person declaration inside of the for loop:-
In struct you adding a value type hence separate values are stored, whereas in class you are adding reference to the object hence gettng same value.
You should understand key distinctions between structs (Value Types) and classes (Reference Type). You could easily find this information in Google or at SO.
When you add struct instance to List you create another separate copy for this instance, and when you change one element you did not change another.
But in case of classes you create one instance and uses this one "shared" instance with two references (list[0] and list1) and you could change this one instance through two different references, that's why when you change list[0] item it seems that you change list1 item too.
Consider following code:
Similar behavior we have when we pass parameter to function (or adding element to list).
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.