4

オブジェクト(作成したクラス)のリスト(C#)があります。リストを使用することはできますが、問題は、オブジェクトクラスの1つだけを作成し(インスタンス化された、適切な用語だと思います)、そのオブジェクトのプロパティがコードの反復によって変化しても、リストに追加し続けることです。 。参照オブジェクトではなく、ハードコードされたオブジェクトをリストに追加できるようにしたいと思います。

これが私が現在行っていることです:

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);  // 
}

XとYは反復によって変化SaveDateするため、リストに追加するオブジェクトは反復ごとに変化しないようにします(つまり、データオブジェクトの履歴を保持できるようにします)。つまり、ハードコードであり、参照として使用しません。

4

4 に答える 4

6

それはできません。リストに追加するたびに新しいオブジェクトを作成する必要があります。そうしないと、古いオブジェクトを変更し続けることになります。

リストに参照型を追加するときは、参照referenceされているオブジェクトではなく、をリストに追加するだけであることに注意してください。これは、常に同じインスタンスをプッシュする場合、リスト内のすべての「アイテム」が実際には同じアイテムであることを意味します。検討:

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

したがって、代わりに、リストに追加するたびにオブジェクトの新しいインスタンスを作成する必要があります。これにより、それらはすべて異なる可能性のある別個のオブジェクトになります。

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);  
    }
}

上記は、各オブジェクトが別個のものであり、ループの複数の反復にわたる「飛行中のオブジェクト」ではないことを前提としています。

ここで、メインオブジェクトが1つあり、そのオブジェクトの「スナップショット」をリストに追加しようとしている場合は、ある種のクローン作成メソッドまたはある種の「コピーコンストラクター」を使用してこれを行うことができます。

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;
    }
}

次に、飛行中のオブジェクトのリストにを追加したい場合はsnapshot、次のようにすることができます。

newSaveDataList.Add(new SaveData(newSaveData));

または、代わりに値型を使用してリストにコピーを配置することもできますが、興味深い癖がたくさんあるため、使用する前にそれらを慎重に検討する必要があります。このトピックに関する投稿がここにありますstructstruct

于 2012-10-26T13:46:17.477 に答える
2

私はあなたが何を求めているのか理解していると思います。履歴値への一連の参照ではなく、最新の状態(xとの値)を反映する同じオブジェクトへの参照のリストを見つけています。y

これは、同じオブジェクトへの参照をリストに追加していることと、毎回新しいオブジェクトを作成するのではなく、この1つの参照オブジェクトを変更しているためです。SaveData問題を解決するために、反復ごとに新しいものを作成できるはずです。

var history = new List<SaveData>();
while (someCondition)
{
    var sd = new SaveData(...);

    if (someOtherCondition)
    {
        sd.saveProperty1 = someValue;
    }

    ...

    history.Add(sd);
}
于 2012-10-26T13:46:59.620 に答える
0

あなたが持っているので、私が思うあなたのサンプルコードは完全に正しくありません

SaveData.save_property1 = x;

私があなたが意味すると思うところ

newSaveData.save_property1 = x;

これを試してください。これは、フィールド値が異なる複数のSaveDataオブジェクトを作成し、オブジェクトをリストに追加する方法を示しています。

List<SaveData> newSaveDataList = new List<SaveData>();
for (int index = 0; index < 10; index++)
{
    SaveData saveData = new SaveData();
    saveData.save_property1 = (double)index;
    saveData.save_property2 = (double)index * 2;
    newSaveDataList.Add(saveData);
}

foreach (SaveData saveData in newSaveDataList)
{
    Console.WriteLine(saveData.save_property1);
    Console.WriteLine(saveData.save_property2);
}
于 2012-10-26T13:54:33.500 に答える
0

動作させるには、新しいオブジェクトを作成し、前のオブジェクトのすべてのフィールドを新しいオブジェクトにコピーしてから、目的のプロパティを変更する必要があります。コピー操作は、自分で実装する必要があるものです。この操作は「クローン作成」と呼ばれます。

次の2つの質問を見てください。

C#で
オブジェクトを複製する.Net(具体的にはC#)でオブジェクトをどのようにディープコピーしますか?

Object.MemberwiseCloneディープコピーが必要ない場合は、次のユーザーを使用することもできます。

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

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

その後:

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

または他の方法:

if (some condition 2) 
{
    newSaveData.save_property2 = y;
    newSaveDataList.Add(newSaveData);
    newSaveData = newSaveData.Clone();
    // from now on all the new changes will happen to a new object, not the one in the list.
}
于 2012-10-26T13:55:10.883 に答える