2

在我的项目中使用静态变量时出现问题(强制使用静态变量)

public static List<int> a = new List<int>();
public static List<List<int>> list = new List<List<int>>();
public Form1()
{
    for (int i = 0; i < 5;i++ )
        a.Add(i);
    list.Add(a);
    Console.WriteLine(list[0].Count); // **count = 5**
    a.RemoveAt(0);
    list.Add(a);
    Console.WriteLine(list[0].Count); // **count = 4** 
    Console.WriteLine(list[1].Count); // count = 4
}

当我使用a.RemoveAt(0)时,它会list[0]改变。为什么会这样,我该如何解决?

4

4 回答 4

5

是的,你指的是同一个对象,因为List<T>它是一个引用类型。请参阅:http: //msdn.microsoft.com/en-us/library/s6938f28.aspx

例如:

List<int> a = new List<int>();
List<int> b = a;
Console.WriteLine(Object.ReferenceEquals(a, b)); //true

a.Add(1);
Console.WriteLine(a[0]); //1
Console.WriteLine(b[0]); //1

a[0] = 9000;
Console.WriteLine(a[0]); //9000
Console.WriteLine(b[0]); //9000

将列表存储在列表中将产生相同的结果:您指向的是相同的原始列表。

如果要存储 in 的副本请制作副本:alist[0]

list.Add(new List<int>(a));

或者使用 linq 让它更简洁:

list.Add(a.ToList());

(确保在using System.Linq;代码文件的顶部添加指令)

于 2013-07-12T12:42:32.017 回答
2

你必须从基础上理解它。Lists对象通过引用工作。当您将 object 添加alist时,这意味着您添加了ato的引用list。现在,您所做的任何更改a都将反映在list[0]它所指的相同参考中。

为了实现这一点,你可以做一些这样的事情。

        var masterList = new List<List<int>>();

        var l1 = new List<int>{1, 2, 3, 4, 5}; // Reference created for l1
        var l2 = new List<int>(); // Reference created for l2

        masterList.Add(l1); // l1 reference added to masterList
        masterList.Add(l2); // l2 reference added to masterList

        l2.AddRange(l1); // This will copy values from l1 reference to l2 reference and will not touch the references

        l2.RemoveAt(0); // First value removed from reference l2 (And therefore it should not affect reference l1)

        MessageBox.Show(masterList[0].Count.ToString() + " and " + masterList[1].Count.ToString());

它必须帮助您了解这里发生的事情。您还必须记住,正如您的问题标题所示,它与静态变量无关。

希望能帮助到你。

于 2013-07-12T12:52:00.467 回答
1

list 保留对 a 的引用,因此如果您更改对象 a 那么 list 中的计数也会更改,因为它引用的是同一件事。

您需要做的是制作 a 的副本并将其传递到列表中,允许列表保留对 a 的单独引用并允许您保持计数相同。

例子:

list.Add(a.ToList()); // See Chris Sinclair's example, full credit to him
于 2013-07-12T12:41:03.770 回答
0

你需要制作列表的副本(因为列表是对a的引用):

        public static List<int> a = new List<int>();
        public static List<List<int>> list = new List<List<int>>();

        for (int i = 0; i < 5; i++)
            a.Add(i);
        list.Add(a.Select(i => i).ToList());//passed in a copy of a.
        Console.WriteLine(list[0].Count); // **count = 5**
        a.RemoveAt(0);
        list.Add(a);
        Console.WriteLine(list[0].Count); // **count = 5** 
        Console.WriteLine(list[1].Count); // count = 4
于 2013-07-12T12:46:51.450 回答