blah blah blah is here! blah blah » Close

up0down
link

I created a method which accepts a parameter of type List<T>. The method then does some operations which fill this list. Single stepping in debug I can see that it does this correctly. However, when it returns from the method all the data in the list is lost.

public void Fill(List<MyClass> myclass)
{
//fill myclass
}

last answered 2 years ago

3 answers

link

That's correct. If the method doesn't return myclass or assign its value to a global- or instance variable, the data will be collected by the Garbage Collector. I recommend doing something like:

public List<MyClass> Fill(List<MyClass> myclass)
{
//fill myclass
return myclass;
}


... and when using it:

List<MyClass> myclass = Fill(new List<MyClass>());

up2down
link

beside this, i'd like to add the pass by reference way for the list:

public void Fill(ref List<MyClass> myclass)
{
//fill myclass
}


and when you want to call it try calling it like this:
List<MyClass> myClass=new List<MyClass>();//a new instance of the Generic list
Fill(ref myClass);//passing the list by reference

eeboy
499

I tried both methods and they work just fine. Are there pros/cons to each method?

foamy
2499

Judging by the title, this is probably what he wanted - I just didn't pick up on that :) ... +1

muster
1556

in the first method that foamy wrote, you copy the stack of the list while passing the parameter. if the list sent is empty the cons won't be that visible but if the list is filled then you are filling ur stack of duplicated data. the pros of this method as well is data safety, where you are keeping the original data safe until the return of the method. the method that uses the ref keyword will send the reference of the list and make changes directly to the list without copying the parameter values. the cons of this method is safety as well, since the data edit is applied directly.

up0down
link

Actually, as List<MyClass> is a reference type then, even if you pass it by value, any additions you make to it in the method should be persisted when the method returns.

What I suspect is happening is that you're inadvertently assigning a new List<MyClass> object to the 'myclass' parameter and then filling that.

This won't be persisted when the method returns because it's a different object to what was passed in.

If this suspicion is correct, then you need to fill the original List<MyClass> object, not instantiate a new one.

Incidentally, if you pass the List<MyClass> variable by reference as muster suggested and then assign a new object to it, the variable will still refer to the new object when the method returns. An 'out' parameter will work similarly except that you don't need to assign anything to the variable before it is passed in - the method itself must do this or the compiler will complain.

EDIT

This simple example illustrates the various scenarios:

using System;
using System.Collections.Generic;

class MyClass
{
public int MyInt {get; set;}

public MyClass(int myInt)
{
MyInt = myInt;
}
}

class Program
{
static void Main()
{
Program p = new Program();

Console.Clear();

Console.WriteLine("Pass by value and fill");
List<MyClass> list = new List<MyClass>();
p.Fill(list);
Console.WriteLine("\n Count is {0}",list.Count); // 1, persisted
Console.WriteLine(" MyInt value is {0}\n", list[0].MyInt); // 1

Console.WriteLine("Pass by value, assign new object and fill");
List<MyClass> list2 = new List<MyClass>();
p.Fill2(list2);
Console.WriteLine("\n Count is {0}\n",list2.Count); // 0, not persisted

Console.WriteLine("Pass by reference, assign new object and fill");
list2.Clear();
p.Fill3(ref list2);
Console.WriteLine("\n Count is {0}",list2.Count); // 1 persisted
Console.WriteLine(" MyInt value is {0}\n",list2[0].MyInt); // 3

Console.WriteLine("Pass as output parameter, assign new object and fill");
List<MyClass> list3;
p.Fill4(out list3);
Console.WriteLine("\n Count is {0}",list3.Count); // 1, persisted
Console.WriteLine(" MyInt value is {0}",list3[0].MyInt); // 4

Console.ReadKey();
}

public void Fill(List<MyClass> myclass)
{
myclass.Add(new MyClass(1));
}

public void Fill2(List<MyClass> myclass)
{
myclass = new List<MyClass>();
myclass.Add(new MyClass(2));
}

public void Fill3(ref List<MyClass> myclass)
{
myclass = new List<MyClass>();
myclass.Add(new MyClass(3));
}

public void Fill4(out List<MyClass> myclass)
{
myclass = new List<MyClass>();
myclass.Add(new MyClass(4));
}

}

Feedback