Hi all,
Probably something very basic but I don’t really understand what’s going on here :
I have a serie of methods that are checking the content of a list, potentially removing invalid entries, then passing on the list to the next method. However, I found out that each method was also changing the list from the previous ones.
Part of the update method :
if (cover3b_PreviousCoverFilter.Count > 0)
{
cover3c_OccupiedSpotsFilter = ExcludeOccupiedCovers(cover3b_PreviousCoverFilter);
}
In other words, in below example, cover3c.Remove also removes an entry from the list cover3b_PreviousCoverFilter (taking generic name “cover” as method argument)
public List<Cover> ExcludeOccupiedCovers (List<Cover> cover)
{
List<Cover> cover3c = cover;
for (int p = cover3c.Count - 1; p >= 0; p--)
{
if (!IsCoverAvailable(cover3c[p]))
{
cover3c.Remove(cover3c[p]); // Also removes entry from cover ??
}
}
return cover3c;
}
Could you guys advise on what I’m missing ?
Thanks !
This is a basic programming concept dealing with whether an argument is passed by “value” or by “reference”. When you pass simple values (ints, floats, structs) to a function, you actually pass a copy of the value. That means you can change it within the function without affecting the original variable passed into it. For example:
void SomeMethod() {
int x = 0;
AnotherMethod(x);
}
void AnotherMethod(int val) {
// Note: This does NOT affect the value of "x" above.
val = val + 1;
}
So, for “simple” objects, copies get passed around. For more complex objects, instead of passing a copy, it passes a “reference” to the object. That means that your method is acting on the same in-memory object, and changes to it will affect the object when you return to the main method. In your case, you’re removing something from the list. There’s only one list, not two. Your method isn’t acting on a copy of the list; it’s acting on the list itself. So, remove a value from it, and it’s gone.
Anyway, what you actually want to do is filter the list at each step, not remove from it. You want to create a new copy of the list, with some elements removed. Look into System.Linq for that. For example, here’s a way to get rid of all elements having a certain value:
var myList = new List<int>() {5,6,7,8,9};
var onlyEvenNumbers = myList.Where(v => v % 2 == 0);
Be sure to include System.Linq to use this syntax. The result, onlyEvenNumbers, will only have the values 6 and 8 in it, without changing the values in myList.
1 Like
I suspected something like that, thanks for the clear explainations !!