tags:

views:

78

answers:

4

Possible Duplicate:
List<int> in c#

I have the following program. I am confused about the output.

The line -
Console.WriteLine(listIsARefType.Count) prints 0 instead of 1. Any idea why ?.

class Program  
{  
   static void Main(string[] args)  
   {  
      ListTest d = new ListTest();  
      d.Test();  
   }  
}


class ListTest   
{   
    public void  ModifyIt(List<int> l)
    {
        l = returnList();
    }

    public void Test()
    {
        List<int> listIsARefType = new List<int>();
        ModifyIt(listIsARefType);
        Console.WriteLine(listIsARefType.Count); // should have been 1 but is 0
        Console.ReadKey(true);
    }

    public List<int> returnList()
    {
        List<int> t = new List<int>();
        t.Add(1);
        return t;
    }
}
+2  A: 

Your ModifyIt method name is misleading: it does not modify the list, it replaces it with a new list.

So while List<int> is a reference type you are passing the reference by value. When you change it to point to a new List inside the method that does not affect the reference in the calling method.

Evgeny
+5  A: 

Everything in .Net is passed by value by default, even reference types. The difference with reference types is that it's the reference itself that's passed by value. So when you call the ModifyIt() function, you pass a copy of the reference to the function. That function then changes the copied reference. The original list reference is still intact and the list is unchanged. Your code should go like this:

void ModifyIt(List<int> t)
{
    t.Add(1);
}

You'll see that now the list does change. You could also do it like this:

void ModifyIt(ref List<int> t)
{
    t = returnList();
}

However, you should favor the former style vs the latter. If you already have something like a returnList() function and you really need a function to add those items to an existing list, do it like this:

void ModifyIt(List<int> t)
{
   t.AddRange(returnList());
}
Joel Coehoorn
+1  A: 

You're creating a new instance of List<int> and assigning it. You cannot do that, because when the function returns, the parameter you passed will still be a reference to the old list.

What you need to do is use the ref parameter like so:

public void  ModifyIt(ref List<int> l)
{
    l = returnList();
}

And then call it like so:

ModifyIt(ref listIsARefType);

You will find that that will function as expected.

rakuo15
+1  A: 

The following line:

List<int> listIsARefType = new List<int>();

creates a new list. The number of items in the list is 0. The next line "modifies" the list (but not really, as that is the problem!)

 ModifyIt(listIsARefType);

So while you think you've added something, you actually have not. Let's look at what happens when the ModifyIt( ) gets called:

l = returnList();

simply assigns a List<int> of Count 1 to l. But - here's the important part:

The reference l is only the parameter. You have not changed what listIsARefType references. And so, listIsARefType still contains 0 items. l contains 1 item but it is lost as soon as ModifyIt( ) is complete.

Other people can better explain what's happening here, and it's important to know. Jon Skeet has this excellent article on Parameter passing in C#.

Charlie Salts