struct在List中时更改结构字段

时间:2016-04-25 11:15:03

标签: c# list

当我从列表中找到某个项目并尝试更改其中一个属性时,它就会保持不变。

// My struct
struct Person
{
    public string name;
    public string surname;
}

// Fill up initial data
persons = new List<Person>();
person = new Person();
person.name = "Name";
person.surname = "Test";
persons.Add(person);

// Here person is found, I can see it by printing person.name and person.surname
Person foundPerson = persons.Find(p => p.surname == "Test");

// Let's change it
foundPerson.name = "Another name";

// But when I print all list's items, the name is still "Name". So previous string hasn't changed the original object.
persons.ForEach(delegate (Person person)
{
    Console.WriteLine("Name: {0}", person.name);
});

我错过了什么?我该怎么做才能更改列表中包含的原始值?

2 个答案:

答案 0 :(得分:4)

因为你正在使用结构。结构按值处理,因此当您编写

Person person list.Find(p => p.surname == "Test"); 

你得到一个人的副本。

使用class而不是struct或write back to list full person struct。

如果您仍想使用struct,可以编写

Person foundPerson = persons.Find(p => p.surname == "Test");
int index = persons.IndexOf(foundPerson);
foundPerson.name = "Another name";
persons[index] = foundPerson;

答案 1 :(得分:2)

这是因为struct是按值对象。当你这样做时

Person foundPerson = persons.Find(p => p.surname == "Test");

foundPerson成为您列表中Person struct的独立副本。对其所做的任何更改都不会反映在原文中。

您可以通过Person class来解决此问题。如果您无法灵活地进行此更改,则可以搜索索引并进行更改,或者将Person视为不可变,并将修改后的foundPerson分配回该位置在存储它的列表中。

您的问题提供了it is a good idea to stay away from mutable structs

的完美说明