我有一组对象,它们具有IEnumerable<string>
我的代码
foreach (var student in students)
{
string term = SomeMethodhere();
students.Where(x => x.Id == student.Id)
.ToList()
.ForEach(x =>
{
x.FieldsOfStudy.ToList().Add(term);
});
}
我没有错误,但FieldsOfStudy
保持不变。
我错过了什么?
答案 0 :(得分:3)
我错过了什么?
ToList()
创建一个 new 列表,其中包含FieldOfStudy
中找到的所有元素。它不会修改原始枚举。
事实上,无法保证任何可以修改原始枚举的内容;很可能FieldsOfStudy
实际上是一个数组(因此不能添加任何元素)。
底线:您不应修改以IEnumerable<T>
提供的内容。如果您希望FieldsOfStudy
是可变的,请将其声明为提供修改列表的方法的接口,例如IList<T>
或ICollection<T>
。
设计理念:如果您将FieldsOfStudy
属性声明为IEnumerable<T>
,则表明从该属性返回的对象可能是任何实现IEnumerable<T>
。如果在调用代码时,您依赖于将该对象转换为更具体的东西(可以添加项目的东西),那么当FieldsOfStudy
属性的实现发生更改时,该调用代码可能会中断。如果可以分配FieldsOfStudy
属性,事情可能会有所不同,因为调用代码可以控制属性中存储的内容。
答案 1 :(得分:2)
x.FieldsOfStudy.ToList()
会生成新实例列表。所以你实际上是在新集合中添加元素。
可能的解决方法(如果您可以将列表的新实例设置为属性FieldsOfStudy
):
{
var list = x.FieldsOfStudy as IList<string> ?? new List<string>(x.FieldsOfStudy);
list.Add(term);
x.FieldsOfStudy = list;
}
答案 2 :(得分:0)
此处循环是为学生制作的,然后每个学生都在同一循环中更新。
可能的解决方案和变化: 提供的研究领域是ICollection或Iist
students.ToList().ForEach(s=>s.FieldsOfStudy.Add(SomeMethodhere()));