在foreach循环中更改对象值?

时间:2013-07-16 12:50:16

标签: c# loops foreach enumeration

在一个地方,我正在使用字符串列表,在这种情况下,我能够将字符串的值更改为下面给出的代码,

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())
{
      studentDTO=ChangeName(studentDTO); //Not working 
}

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

错误是:无法分配,因为它是迭代变量

2 个答案:

答案 0 :(得分:24)

您无法更改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

答案 1 :(得分:19)

你实际上并没有改变你所指的对象,所以你可以使用:

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

或者仍然调用方法:

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

在这两种情况下,代码都不会更改迭代变量(student)的值,所以没关系。

但是你的原始示例无论如何都不会编译 - foreach循环引入的迭代变量是只读的。