C# 在 foreach 循环中更改对象值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17676974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing objects value in foreach loop?
提问by
In one place i am using the list of string in that case the i am able to change the value of the string as code given below,
在一个地方,我正在使用字符串列表,在这种情况下,我可以将字符串的值更改为下面给出的代码,
foreach(string item in itemlist.ToList())
{
item=someValue; //I am able to do this
}
But for object of class i am not able to alter the members value of the object the code is as below,
但是对于类的对象,我无法更改对象的成员值,代码如下,
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;
}
Error is : Can not assign because it's iteration variable
错误是:无法分配,因为它是迭代变量
采纳答案by Olivier Jacot-Descombes
You cannot change the iteration variable of a foreach-loop, but you can change members of the iteration variable. Therefore change the ChangeName
method to
您不能更改 foreach 循环的迭代变量,但可以更改迭代变量的成员。因此将ChangeName
方法更改为
private void ChangeName(StudentDTO studentDTO)
{
studentDTO.name = SomeName;
}
Note that studentDTO
is a reference type. Therefore there is no need to return the changed student. What the ChangeName
method gets, is not a copy of the student but a reference to the unique student object. The iteration variable and the studentDTOList
both reference the same student object as does the studentDTO
parameter of the method.
请注意,这studentDTO
是一个引用类型。因此,无需返回已更改的学生。该ChangeName
方法得到的不是学生的副本,而是对唯一学生对象的引用。迭代变量和studentDTOList
两者都引用相同的学生对象作为studentDTO
方法的参数。
And change the loop to
并将循环更改为
foreach(StudentDTO student in studentDTOList)
{
ChangeName(student);
}
However, methods like ChangeName
are unusual. The way to go is to encapsulate the field in a property
然而,像这样ChangeName
的方法是不寻常的。要走的路是将字段封装在一个属性中
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
You can then change the loop to
然后您可以将循环更改为
foreach(StudentDTO student in studentDTOList)
{
student.Name = SomeName;
}
EDIT
编辑
In a comment you say that you have to change many fields. In that case it would be okay to have a method UpdateStudent
that would do all the changes; however I still would keep the properties.
在评论中,您说您必须更改许多字段。在那种情况下,可以使用一种方法UpdateStudent
来完成所有更改;但是我仍然会保留这些属性。
If there is no additional logic in the properties besides passing through a value, you can replace them by the handy auto-implemented properties.
如果属性中除了传递值之外没有其他逻辑,您可以将它们替换为方便的自动实现的属性。
public string Name { get; set; }
In that case you would have to drop the field name
.
在这种情况下,您将不得不删除该字段name
。
回答by Jon Skeet
You're not actually changing the object that you're referring to anyway, so you can just use:
无论如何,您实际上并没有更改您所指的对象,因此您可以使用:
foreach (StudentDTO student in studentDTOList)
{
student.name = SomeName;
}
Or still call a method:
或者仍然调用一个方法:
foreach (StudentDTO student in studentDTOList)
{
ChangeStudent(student);
}
In both cases, the code doesn't change the value of the iteration variable (student
) so it's okay.
在这两种情况下,代码都不会更改迭代变量 ( student
)的值,所以没问题。
But your original example doesn't compile anyway - an iteration variable introduced by a foreach
loop is read-only.
但是您的原始示例无论如何都无法编译 - 循环引入的迭代变量foreach
是只读的。