Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List holding references

Tags:

c#

I have a List (in C#) of an object (class that I created). I am able to use the list but the problem is that I only created (instantiated I think is the proper term) one of my object class and I keeping adding it to the list even though the properties of that object change with iterations of the code. I would like to be able to add hardcoded objects to my list and not the reference object.

Here is what I am currently doing:

public class SaveData
{
    public double save_property1;
    public double save_property2;    
}

in the application

SaveData newSaveData = new SaveData();
List<SaveData> newSaveDataList = new List<SaveData>;

if ( some condition)
{
    newSaveData.save_property1 = x
}

if (some condition 2) 
{
    newSaveData.save_property2 = y 
    newSaveDataList.Add(SaveData);  // 
}

Since X and Y change over the iterations, I want the SaveDate object I add to the list NOT to change with each iteration (so I can keep a history of the Data objects), i.e. hardcode and not use as reference.

like image 455
AbeeCrombie Avatar asked Feb 18 '23 16:02

AbeeCrombie


1 Answers

You can't do that, you will need to create a new object each time you want to add to the list or you will just keep modifying the old one.

Remember that when you add a reference type to the list, you are just putting the reference into the list and not the object being referred to. This means that if you always push the same instance, all "items" in the list are really the same item. Consider:

newSaveData                        1000
+-----------+                      +--------------------+
| 1000      |--------------------->| save_property1     |
+-----------+                      | save_property2     | 
                                   +--------------------+
newSaveDataList                               ^
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+

So instead, you need to create a new instance of the object for each add to the list, so that they are all distinct objects that can vary:

while (yourLoopCondition)
{
    // each item you want to add, create a new instance.
    newSaveData = new SaveData();
    if (someCondition1)
    {
        newSaveData.save_property1 = x
    }

    if (someCondition2) 
    {
        newSaveData.save_property2 = y 
        newSaveDataList.Add(newSaveData);  
    }
}

The above assumes that each object is distinct and not an "object in flight" across multiple iterations of the loop.

Now, if you have one main object and you're just trying to put a "snapshot" of that object in the list, you could do this with some sort of cloning method or "copy constructor" of sorts:

public class SaveData
{
    public double save_property1;
    public double save_property2;

    public SaveData(SaveData other)
    {
        save_property1 = other.save_proerty1;
        save_property2 = other.save_property2;
    }
}

Then if you want to put a snapshot on the list of an object in flight, you could do:

newSaveDataList.Add(new SaveData(newSaveData));

Or, you could use a struct instead which is a value type and thus would place a copy in the list, but struct has a lot of interesting quirks and one should consider those very carefully before using them. I have a post on this topic here

like image 149
James Michael Hare Avatar answered Mar 05 '23 21:03

James Michael Hare