29

ある場所では、文字列のリストを使用しています。その場合、以下に示すコードとして文字列の値を変更できます。

foreach(string item in itemlist.ToList())
{
    item = someValue; //I am able to do this 
}

しかし、クラスのオブジェクトの場合、オブジェクトのメンバー値を変更することはできません。コードは次のとおりです。

public class StudentDTO
{
    string name;
    int rollNo;
}

studentDTOList=GetDataFromDatabase();

foreach(StudentDTO student in studentDTOList.ToList())
{
      student = ChangeName(student); //Not working 
}

private StudentDTO ChangeName(StudentDTO studentDTO)
{
     studentDTO.name = SomeName;
     return studentDTO;
}

エラー: 反復変数であるため代入できません

4

2 に答える 2

37

foreach ループの反復変数は変更できませんが、反復変数のメンバーは変更できます。したがって、ChangeNameメソッドを次のように変更します

private void ChangeName(StudentDTO studentDTO)
{
    studentDTO.name = SomeName;
}

studentDTO参照型であることに注意してください。したがって、変更された学生を返却する必要はありません。メソッドが取得するChangeNameのは、学生のコピーではなく、一意の学生オブジェクトへの参照です。反復変数とその両方は、メソッドのパラメーターstudentDTOListと同じ学生オブジェクトを参照します。studentDTO

そして、ループを次のように変更します

foreach(StudentDTO student in studentDTOList)
{
    ChangeName(student);
}

ただし、次のような方法ChangeNameは珍しいです。行く方法は、フィールドをプロパティにカプセル化することです

private string name;
public string Name
{
    get { return name; }
    set { name = value; }
}

その後、ループを次のように変更できます

foreach(StudentDTO student in studentDTOList)
{
    student.Name = SomeName;
}

編集

コメントで、多くのフィールドを変更する必要があると言っています。UpdateStudentその場合、すべての変更を行うメソッドがあれば問題ありません。ただし、プロパティは保持します。

値を渡す以外にプロパティに追加のロジックがない場合は、便利な自動実装プロパティに置き換えることができます。

public string Name { get; set; }

その場合、フィールドをドロップする必要がありますname

于 2013-07-16T13:03:16.937 に答える
21

とにかく参照しているオブジェクトを実際に変更しているわけではないので、次を使用できます。

foreach (StudentDTO student in studentDTOList)
{
    student.name = SomeName;
}

または、メソッドを呼び出します。

foreach (StudentDTO student in studentDTOList)
{
    ChangeStudent(student);
}

どちらの場合も、コードは反復変数 ( student) の値を変更しないので問題ありません。

しかし、元の例はとにかくコンパイルされません-foreachループによって導入された反復変数は読み取り専用です。

于 2013-07-16T12:52:26.877 に答える