The List<T>
sending by default by ref, so why does this not work?
No, all parameters that are not specially marked, are passed by value (and it goes for both reference types and value types). If you changed your method into ref
it would work:
private static void SortDesc(ref List<Items> items)
{
items = items.OrderByDescending(x => x.Neto).ToList();
}
The point here, as was also explained in Farhad's answer, is that .ToList()
creates a new instance of List<Items>
. The old instance is unchanged. The assignment items = ...
above changes the value of the reference (from referring the original instance to referring the new instance), so if the parameter is by value it will not work.
Since you make a new instance, it is probably better to just return it directly:
private static List<Items> SortDesc(List<Items> items)
{
return items.OrderByDescending(x => x.Neto).ToList();
}
However, since you made your method void
, maybe you wanted to sort the same list and not create another list?
In that case there are some possibilities. One is to use the Sort
method on List<>
, like this:
private static void SortDesc(List<Items> items)
{
items.Sort((x, y) => y.Neto.CompareTo(x.Neto)); // unstable
}
or:
private static void SortDesc(List<Items> items)
{
items.Sort((x, y) => Comparer<Xxx>.Default.Compare(y.Neto, x.Neto)); // unstable
}
where Xxx
denotes the declared (compile-time) type of the Neto
property. The first (simpler) of these two works fine if .Neto
is never a null reference (including the case where Xxx
is a value type).
These are descending because we swap x
and y
after the lambda arrow.
Warning: Unstable means that if some Items
in the List<>
have equally small .Neto
, there is no telling what the order of these is going to be. This is not equivalent to the earlier examples which are stable.
If you need Linq OrderByDescending
or need stable sort, you might try the following (although it is not pretty):
private static void SortDesc(List<Items> items)
{
var tempList = items.OrderByDescending(x => x.Neto).ToList();
items.Clear();
items.AddRange(tempList);
}
Instead of Clear
and AddRange
you can also copy the list entries explicitly with a for
loop containing items[i] = tempList[i]
.