4
public class Foo
{
    public static List<long> myList = new List<long>() { 1,2,3 }
}

在另一种方法中:

var testList = Foo.myList;

如果我在最后一行放置一个断点并检查testList它会不时给我不同的长度。

当我使用它时ToList()Foo.myList它似乎表现正确。但为什么?

编辑:

我的问题是我进行了 ajax 调用 > 修改Foo.myList> 新 ajax 调用 >Foo.myList再次获取并获得了修改后的值。

4

2 回答 2

8

共享状态的竞争条件。静态字段成员意味着只有一个副本,因此如果您在代码中操作列表,则使用该属性的所有线程都会更改。ToList()之所以有效,是因为它创建了一个不会改变原始列表的列表副本,但请注意,如果对象是引用类型,则此副本指向与原始列表相同的对象。因此,更改副本中的引用类型也会更改原始列表中的值......但因为long是一种在这里不适用的值类型。

如果您希望您的列表是只读的http://msdn.microsoft.com/en-us/library/e78dcd75.aspx

于 2013-06-30T17:26:32.057 回答
3

听起来您正在修改 Foo.myList 或某处对其的引用。请注意,将列表分配给局部变量不会复制。因此:

var list = new List<long> { 1, 2, 3 };
var testList = list;
testList.Add(4); // list is now [1, 2, 3, 4]
list.Add(5); // testList is now [1, 2, 3, 4, 5]

另一方面,ToList() 会进行复制。一般来说,将任何静态列表设为只读(如果这是您想要的语义)可能是最安全的,以防止这种情况意外发生:

public class Foo {
    // pre .NET 4.5, use ReadOnlyCollection<T> (which implements IList<T>)
    public static readonly IReadOnlyList<long> myList = new List<long> { 1, 2, 3 }.AsReadOnly();
}

var testList = Foo.myList.ToList(); // get an editable copy
var testList2 = Foo.myList; // get a reference to the immutable static list
于 2013-06-30T17:29:05.830 回答