无法更新通用列表的内容

时间:2010-12-03 13:41:17

标签: c# generics

我有一个简单的类,它有布尔字段:

public struct Foo { bool isAvailable; }

现在我有一个foos列表:

List < Foo >  list = new List< Foo >();

稍后我会列出列表中的每个foo并尝试更新其isAvailable字段:

foreach(Foo foo in list) {
    foo.isAvailable = true; 
}

但上面的代码永远不会更新列表。我在这里做错了什么,以及它的补救措施。

3 个答案:

答案 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);

您在每个对象的堆栈上的相同内存位置上引用。