列出持有参考

Abe*_*bie 4 c#

我有一个对象的List(在C#中)(我创建的类).我能够使用列表,但问题是我只创建(实例化我认为是正确的术语)我的一个对象类,并且我继续将它添加到列表中,即使该对象的属性随着代码的迭代而改变.我希望能够将硬编码对象添加到我的列表而不是参考对象.

这是我目前正在做的事情:

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);  // 
}
Run Code Online (Sandbox Code Playgroud)

由于X和Y在迭代中发生变化,我希望SaveDate我添加到列表中的对象不会随着每次迭代而改变(因此我可以保留Data对象的历史记录),即硬编码而不是用作参考.

Jam*_*are 6

您不能这样做,每次要添加到列表时都需要创建一个新对象,否则您将继续修改旧对象.

请记住,当您向列表添加引用类型时,您只是将其reference放入列表而不是引用的对象.这意味着如果您始终推送同一个实例,则列表中的所有"项目"实际上都是相同的项目.考虑:

newSaveData                        1000
+-----------+                      +--------------------+
| 1000      |--------------------->| save_property1     |
+-----------+                      | save_property2     | 
                                   +--------------------+
newSaveDataList                               ^
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+                                 |
| 1000      |---------------------------------+
+-----------+
Run Code Online (Sandbox Code Playgroud)

因此,您需要为每个添加到列表的对象创建一个新的对象实例,以便它们都是可以变化的不同对象:

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);  
    }
}
Run Code Online (Sandbox Code Playgroud)

以上假设每个对象是不同的,而不是循环的多次迭代中的"飞行中的对象".

现在,如果你有一个主要对象并且你只是想在列表中放置该对象的"快照",你可以使用某种克隆方法或类别的"复制构造函数"来实现:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果你想snapshot在飞行中的对象列表上放置一个,你可以这样做:

newSaveDataList.Add(new SaveData(newSaveData));
Run Code Online (Sandbox Code Playgroud)

或者,你可以使用一个struct值,它是一个值类型,因此会在列表中放置一个副本,但struct有很多有趣的怪癖,在使用它们之前应该仔细考虑它们.我在这里有关于这个主题的帖子