List <long>属性</long>的行为不一致

时间:2013-06-30 17:22:06

标签: c# asp.net

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

另一种方法:

var testList = Foo.myList;

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

当我在ToList()上使用Foo.myList时,它似乎行为正确。但为什么呢?

修改

我的问题是我做了一个ajax调用&gt;修改后的Foo.myList&gt;新的ajax电话&gt;再次获取Foo.myList并获得修改后的值。

2 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分: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