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 回答