Reputation: 23
I have problem when using static variable in my project (force using static variable)
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
}
When I use a.RemoveAt(0)
, it makes list[0]
change. Why does it do this and how can I fix it?
Upvotes: 2
Views: 744
Reputation: 11687
You must understand it from basics. Lists
objects work through reference. When you added object a
to list
, that means you added a reference of a
to list
. Now what ever you change in a
that will be reflected in list[0]
also as it is referring to same reference.
To achieve this, you can do some like this.
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());
It must help you to understand whats happening here. You must also remember that it has NOTHING to do with static variables as your question heading indicates.
Hope it helps.
Upvotes: 2
Reputation: 23198
Well yeah, you're referring to the same object because List<T>
is a reference type. See: http://msdn.microsoft.com/en-us/library/s6938f28.aspx
For example:
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
Storing a list in a list will yield the same result: you are pointing to the same original list.
If you want to store a copy of a
in list[0]
, then make a copy:
list.Add(new List<int>(a));
Or use linq to make it more succinct:
list.Add(a.ToList());
(make sure to add a using System.Linq;
directive to the top of your code file)
Upvotes: 5
Reputation: 4542
you need to make copy of list(because list is keep+ing a reference to 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
Upvotes: 0
Reputation: 2387
list is keeping a reference to a so if you change the object a then the count in list will also change because it refers to the same thing.
What you need to do is make a copy of a and pass that into list, allowing list to keep a separate reference to a and allowing you to keep the count the same.
Example:
list.Add(a.ToList()); // See Chris Sinclair's example, full credit to him
Upvotes: 1