We speak about Reference Types, Values Types very often and it’s common knowledge that Value Types are stored on stack and Reference Types are stored on heap. Value type contains values, and Reference Type contains address pointed to that memory location.
Have you ever thought what can be the impact while dealing with the collection of these types? Well, in most cases it’s pretty simple as we deal with the collection of Value Types, it’s like adding the value types (for short let’s consider the simple value type “int”) into the collection, loop through the collection, (manipulate it while adding into the list or while looping through the list), and show the final output.
/// <summary> /// Example Class comprising of simple properties like Number & Message /// </summary> public class ClassEx { public int NUMBER { get; set; } public string MESSAGE { get; set; } /// <summary> /// Overridden toString() method to return value of number and message /// </summary> public override string ToString() { return "Number is: " + NUMBER + "\n" + MESSAGE + "\n"; } }
(Note: to know more about overriding ToString(), please visithttp://www.mindfiresolutions.com/Override-ToString-method-in-C-299.php )
Now create a console application, and here declare the object of ClassEx, let’s say initialObj
ClassEx initialObj = new ClassEx();
And also declare a List<ClassEx> arrayList which will contain the list of ClassEx objects, like
List<ClassEx> arrObjects = new List<ClassEx>();
Now add initialObj 10 times with different properties to this collection like, //add ten Objects to array
for (int tenItems = 1; tenItems <= 10; tenItems++)
{
initialObj.NUMBER = tenItems;
initialObj.MESSAGE = “This is Object Number: ” + tenItems;
arrObjects.Add(initialObj);
}
Finally loop through the collection and call the ToString method of ClassEx
foreach(var item in arrObjects)
{
Console.WriteLine(item.ToString());
}
The output will be :
Number is: 10
This is Object Number: 10
Number is: 10
This is Object Number: 10
Number is: 10
This is Object Number: 10
…
…,
like this for 10 times. Why?! Obviously the answer will come that It is a reference type that’s why, The value of the original object is changed, there’s only a single object. Correct 100% correct, whatever these line speaks about, but does this explains the whole stuff?? |
Not making much sense ? Let us twist this example a little extra. Let’s change our code where we add initialObject to array, (everything before this remains the same).add initialObj 10 time to collection like-
//add ten Objects to array for (int tenItems = 1; tenItems <= 10; tenItems++) { arrObjects.Add(initialObj); } loop through the collection, change the properties and call the ToString method of ClassEx
int countItems =1;
foreach(var item in arrObjects)
{
initialObj.NUMBER = countItems;
initialObj.MESSAGE = “This is Object Number: ” + countItems;
Console.WriteLine(item.ToString());
countItems++;
}
Now what will be the output ? this time you will have to guess as it’s a totally new output as anyone with an elementary knowledge on C would predict.
Number is: 1
This is Object Number: 1
Number is: 2
This is Object Number: 2
Number is: 3
This is Object Number: 3
Number is: 4
This is Object Number: 4
………..
and so on increasing
…………
…………
Number is: 10 Now what?
How can there be 10 different results?
Is there 10 objects created? If No, then how 10 different results are printed, If yes, how? as we never changed the logic related to classes, we just changed the code a little – picking up first 2 lines from first “for” loop, and then put it into the next “foreach” loop.
We all know the answers, it’s just that we need to think a little different.
Whenever we create the Object of ClassEx, it does a memory allocation for the object and creates a reference for that object.
Now think again,
ClassEx initialObj = new ClassEx();
Whenever we reference this initialObj, it will mean we are referencing addressAX1000 and the values present at this address.
Fine, now start adding this address to our List collection like,
Start adding this address to our List collection like, for (int tenItems = 1; tenItems <= 10; tenItems++)
{
arrObjects.Add(initialObj);
}
for (int tenItems = 1; tenItems <= 10; tenItems++)
{
initialObj.NUMBER = tenItems;
initialObj.MESSAGE = “This is Object Number: ” + tenItems;
arrObjects.Add(initialObj);
Simplify this in terms of memory space, it says that we are adding address (AX1000) ten times to List arrObjects,so, now there is only one memory address that is present in arrList for 10 times. Now comes, the reason for our output, output number 1, consider the following line..
for (int tenItems = 1; tenItems <= 10; tenItems++)
initialObj.NUMBER = tenItems;
initialObj.MESSAGE = “This is Object Number: ” + tenItems;
arrObjects.Add(initialObj);
}
This address AX1000 is being added to arraylist with each time the properties changed. But this has no effect as we are not doing anything with this changing value at each loop count. So with the final Entry of initialObject the values present at AX1000 is NUMBER: 10, MESSAGE: This is Object Number: 10
So what if we loop through our collection and call the overridden ToString(),
foreach(var item in arrObjects) {
Console.WriteLine(item.ToString());
}
Well it is going to read the value present at the address AX100 and print it on the screen which is, and it will loop for 10 times as collection contains AX1000address 10 times.
Number is: 10
This is Object Number: 10
…..
….
Again for our 2nd output, it does the same adding Address AX1000 in the collection for 10 times, except the fact that before showing the value, it changes the value as well present at address AX1000.
i.e.
int countItems =1;
foreach(var item in arrObjects)
{
initialObj.NUMBER = countItems;
initialObj.MESSAGE = “This is Object Number: ” + countItems;
Console.WriteLine(item.ToString());
countItems++;
}
will print the output with different values, which will be :
Number is: 1
This is Object Number: 1
………..
and so on increasing
…………
…………
Number is: 10
This is Object Number: 10
But the main point is whenever the loop ends, the final value present at address AX1000 still remains the same i.e. NUMBER: 10, MESSAGE: This is Object Number: 10.
So, if we want that our collection should contain different objects (different addresses) each having a different value for the properties, we’ll have to create a new instance of object and then add it to the collection, so it will be like
for (int tenItems = 1; tenItems <= 10; tenItems++)
{
initialObj = new ClassEx();
arrObjects.Add(initialObj);
}
This line means a memory space (let’s say 5 bytes) has been allocated at memory address AX1000 (some hexadecimal number). |