我在项目中使用静态变量时遇到问题(强制使用静态变量)
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]
发生变化。为什么会这样做,我该如何解决?
答案 0 :(得分: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
在列表中存储列表会产生相同的结果:您指向到同一原始列表。
如果您想在a
中存储list[0]
的副本,请复制一份:
list.Add(new List<int>(a));
或者使用linq使其更简洁:
list.Add(a.ToList());
(确保在代码文件的顶部添加using System.Linq;
指令)
答案 1 :(得分:2)
你必须从基础知识中理解它。 Lists
个对象通过引用工作。当您将对象a
添加到list
时,这意味着您向a
添加了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());
它必须帮助你理解这里发生的事情。您还必须记住它与静态变量无关正如您的问题标题所示。
希望它有所帮助。
答案 2 :(得分:1)
list是保持对a的引用,如果你改变了对象a,那么列表中的count也会改变,因为它引用同样的东西。
你需要做的是复制a并将其传递到列表中,允许列表单独引用a并允许你保持计数相同。
示例:
list.Add(a.ToList()); // See Chris Sinclair's example, full credit to him
答案 3 :(得分: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