我有一个简单的类,它有布尔字段:
public struct Foo { bool isAvailable; }
现在我有一个foos列表:
List < Foo > list = new List< Foo >();
稍后我会列出列表中的每个foo并尝试更新其isAvailable字段:
foreach(Foo foo in list) {
foo.isAvailable = true;
}
但上面的代码永远不会更新列表。我在这里做错了什么,以及它的补救措施。
答案 0 :(得分:7)
这是因为Foo
是一个可变结构。
当您从列表中获取值时,它正在制作副本 - 因为这是值类型的行为方式。您正在更改副本,保持原始值不变。
建议:
虽然可以更改代码以便以不同的方式迭代列表并且每次都替换值,但这样做通常是个坏主意。只需使用一个类......或将您的列表投影到具有适当值的 new 列表。
原始答案,当Foo是一个班级时
应该可以正常工作。例如,这是 工作的简短但完整的程序:
using System.Collections.Generic;
public class Foo
{
public bool IsAvailable { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name + ": " + IsAvailable;
}
}
class Test
{
static void Main()
{
List<Foo> list = new List<Foo>()
{
new Foo { Name = "First", IsAvailable = true },
new Foo { Name = "Second", IsAvailable = false },
new Foo { Name = "Third", IsAvailable = false },
};
Console.WriteLine("Before:");
list.ForEach(Console.WriteLine);
Console.WriteLine();
foreach (Foo foo in list)
{
foo.IsAvailable = true;
}
Console.WriteLine("After:");
list.ForEach(Console.WriteLine);
}
}
尝试将您当前的代码调整为类似的简短但完整的程序不工作,发布,我们可以解决正在发生的事情。
答案 1 :(得分:2)
您使用的结构为Foo
,而不是类。结构被复制,未被引用,因此您只修改副本而不是列表中存储的对象。
所以你基本上有两个选择:
让它成为一个类
将结果重新分配到列表中。为此,我将使用索引而不是使用foreach
迭代。
答案 2 :(得分:0)
填写列表时,需要为每个Foo类创建新的istance。
List list = new List(); Foo foo = new Foo();
foo.isAvailable = false; list.Add(FOO);
foo = new Foo(); list.Add(FOO);
foo = new Foo(); list.Add(FOO);
如果你这样填写:
List list = new List(); Foo foo = new Foo(); list.Add(FOO); list.Add(FOO); list.Add(FOO);
您在每个对象的堆栈上的相同内存位置上引用。