请参阅以下人员类:
public class Person
{
int _id { get; set; }
string _name { get; set; }
public Person (int id, string name)
{
_id = id;
_name = name;
}
public Person()
{
}
public IEnumerable<Person> GetPeople()
{
_id = 1;
_name = "James";
yield return this;
_id = 2;
_name = "Michael";
yield return this;
_id = 3;
_name = "Sarah";
yield return this;
}
}
以及下面的客户端代码:
Person p1 = new Person();
IEnumerable<Person> personEnumerable = p1.GetPeople();
List<Person> personList = personEnumerable.ToList();
为什么PersonList在运行之后包含Sarah的三个条目?在客户端中填充personList的最佳方法是什么?
答案 0 :(得分:6)
因为GetPeople
不创建新实例,但修改当前实例并返回3次。
以下代码生成预期结果:
public static IEnumerable<Person> GetPeople()
{
yield return new Person(1, "James");
yield return new Person(2, "Michael");
yield return new Person(3, "Sarah");
}
答案 1 :(得分:3)
你应该看到这种行为,对吧?
var p1 = new Person(1, "Tom");
var p2 = p1;
p2._id = 2;
// now p1._id is 2 as well!
这正是这里发生的事情。在第一个return this
之后,再次使用ID 2修改this
并命名为Michael。这会导致返回的this
也会更改,因为它们引用同一个对象。您从未使用new
创建新对象。第三次收益率回报也是如此。
要解决此问题,只需将Person
更改为结构(因此它现在是值类型),或者在JanDotNet的答案中实现该方法。