2

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?

4
  • 1
    because list[0] contains a so if you remove sth from a list[0].Count is different. It's not because of static, it's because list[0] contains reference to object a Commented Jul 12, 2013 at 12:38
  • 2
    Well yeah, you're referring to the same object. If you want to store a copy of a in list[0], then make a copy: list.Add(a.ToList()); (make sure to add a using System.Linq; directive) Commented Jul 12, 2013 at 12:39
  • 1
    what are you trying to archieve with this code? Commented Jul 12, 2013 at 12:39
  • 1
    Like @ChrisSinclair said, you need to make a copy. But please explain what you're doing -- why do you have a list of lists if you don't want them to actually refer to the source lists? Are you sure you don't just want a straight list? You can add all the elements of one list to another with AddRange. Commented Jul 12, 2013 at 12:47

4 Answers 4

5

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)

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1

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

2 Comments

This doesn't actually make a copy of a; it again is pointing to the same reference.
You're right I apologise, I've updated referring to your answer
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.