3

lstCopy で元のリスト lstStudent のコピーを作成し、lstCopy を変更関数に送信すると、lstStudent も変更されます。このリストは変更せずに残しておきたいと思います。

List<Student> lstStudent = new List<Student>();
Student s = new Student();
s.Name = "Akash";
s.ID = "1";
lstStudent.Add(s);
List<Student> lstCopy = new List<Student>(lstStudent);
Logic.ModifyList(lstCopy);
// "Want to use lstStudent(original list) for rest part of the code"

public static void ModifyList(List<Student> lstIntegers) { 
    foreach (Student s in lstIntegers) { 
        if (s.ID.Equals("1")) { 
            s.ID = "4"; s.Name = "APS"; 
        } 
    } 
}
4

5 に答える 5

3

バイナリ フォーマッタを使用して、複製可能なインターフェイスを使用せずにこれを実現することもできます。

void Main()
{
   var student1=new Student{Name="Bob"};
   var student2=new Student{Name="Jim"};

   var lstStudent=new List<Student>();
   lstStudent.Add(student1);
   lstStudent.Add(student2);

   var lstCopy=new List<Student>(lstStudent);
   var clone=Clone(lstStudent);

   student1.Name="JOE";

   lstCopy.Dump();
   lstStudent.Dump();
   clone.Dump();

}

public List<Student> Clone(List<Student> source)
{

   BinaryFormatter bf=new BinaryFormatter();
   using(var ms=new MemoryStream())
   {
     bf.Serialize(ms,source);
     ms.Seek(0,0);
     return (List<Student>)bf.Deserialize(ms);
   }
}

[Serializable]
public class Student
{
  public string Name { get; set; }
}

出力:

5List<Student> (2 items) 4  
Name 
JOE 
Jim 

5List<Student> (2 items) 4  
Name 
JOE 
Jim 

5List<Student> (2 items) 4  
Name 
Bob 
Jim 

コードはLINQPadにダンプするためにフォーマットされています

編集: これは、実装できない状況でのオプションICloneableです。該当する場合は、インターフェイスにコーディングします。つまり、ICloneable学生オブジェクトに実装し、メソッドでBinaryFormatterロジックを使用できます。Clone()ただし、開発者として、何をしたいかを自分で決めるオプションがあります。オプションは必ずしもアドバイスではなく、アドバイスは常にオプションではありません。タスクを完了するために必要なことをしなければならない場合があり、その場合にオプションが必要になります。

これはかなり広く受け入れられているディープ クローン作成方法です。.NET でオブジェクトのディープ コピーを作成するにはどうすればよいでしょうか (具体的には C#)。

于 2012-11-06T04:18:38.210 に答える
2

ICloneable を見てみましょう。あなたが求めているのは「ディープコピー」です。この投稿には多くの良い情報があります:

C#で汎用リストを複製するにはどうすればよいですか?

于 2012-11-06T04:10:47.077 に答える
1

LINQ を使用してリストをコピーするもう 1 つの簡単な方法

List<student> oldList = new List<student> { new student{
                                             id=122,
                                             name="John"} };

IEnumerable<student> copy= oldList.Select(item => new student{
                                             id = item.id,
                                             name = item.name });

List<student> newList= new List<student>(copy);

しかし、最善の選択肢は、ICloneable を実装してオブジェクトをディープ コピーすることです。

于 2012-11-06T04:39:07.047 に答える
0

リストのディープ コピーが必要です。現在、それは浅いコピーです。同じ変数への参照が 2 つあるだけです。C++ などの言語のように、C# でディープ コピーを取得する簡単な方法はありません。ディープ コピーを取得する 1 つの方法は、最初のリストをシリアル化および逆シリアル化することです。以下は、オブジェクトのディープ コピーを取得するためのテンプレート化された関数です。

public static T getDeepCopy<T>( T objectToCopy )
{
    T temp;
    using ( MemoryStream ms = new MemoryStream() )
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize( ms, objectToCopy );
        ms.Position = 0;
        temp = (T)formatter.Deserialize( ms );
    }
    return temp;
}

これらの名前空間も含める必要があります。

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

次に、次のように関数を呼び出すことができます。

lstCopy = getDeepCopy<List<Student>>(lstStudents);
于 2012-11-06T04:45:43.517 に答える
0

Student型がクラス (参照型) の場合、リストにはそれらのインスタンスへの参照のみが含まれます。これは、リストのコピーを作成すると、コピーされたリストにも同じStudentインスタンスを指す参照のみが含まれることを意味します。リストをコピーすることで、インスタンスではなく参照を複製するだけです。コピー後の内容は次のとおりです。

List 1            List 2                     instance S1
ref to S1         ref to S1                  Name: Akash
ref to S2         ref to S2                  ...
...               ...

したがって、次のようなことを行うとlist1[0].Name = "Jim"、インスタンスが更新S1され、両方のリストが同じインスタンスのセットを参照するため、両方のリストに変更が表示されます。

この場合、リストだけでなく、リストのすべてのオブジェクトのクローンを作成する必要があります。すべてのオブジェクトもクローンする必要がありますStudent。これをディープコピーと呼びます。このようなもの:

class StudentList : List<Student>, ICloneable
{
    public object Clone ()
    {
        StudentList oNewList = new StudentList ();

        for ( int i = 0; i < Count; i++ )
        {
            oNewList.Add ( this[i].Clone () as Student );
        }

        return ( oNewList );
    }
}

これを次のように呼び出します。

StudentList oClonedList = lstStudent.Clone () as StudentList;

Studentインターフェイスを実装して、クラスを複製可能にする必要もありICloneableます。

Studentただし、この後、2 つの独立したオブジェクトセットを持つ 2 つの個別のリストが作成されることを忘れないでください。1 つのStudentインスタンスを変更しても、他のリストの生徒には影響しません。

于 2012-11-06T04:05:30.430 に答える