106

I have the following code:

public class CategoryNavItem
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Icon { get; set; }

    public CategoryNavItem(int CatID, string CatName, string CatIcon)
    {
        ID = CatID;
        Name = CatName;
        Icon = CatIcon;
    }
}

public static List<Lite.CategoryNavItem> getMenuNav(int CatID)
{
    List<Lite.CategoryNavItem> NavItems = new List<Lite.CategoryNavItem>();

    -- Snipped code --

    return NavItems.Reverse();
}

But I get the following error:

Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<Lite.CategoryNavItem>'

Any ideas why this might be?

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Tom Gullen
  • 61,249
  • 84
  • 283
  • 456

8 Answers8

164

Try:

NavItems.Reverse();
return NavItems;

List<T>.Reverse() is an in-place reverse; it doesn't return a new list.

This does contrast to LINQ, where Reverse() returns the reversed sequence, but when there is a suitable non-extension method it is always selected in preference to an extension method. Plus, in the LINQ case it would have to be:

return someSequence.Reverse().ToList();
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    FYI for those who want to reverse an array this doesn't work, you need to call Array.Reverse(array) instead. – Iain Ward Jul 12 '16 at 16:16
  • 18
    Just suffered from an interesting special case: When a variable is declared as `List list`, then `list.Reverse()` calls the in-place version. Then, a fellow developer is extra smart and changes the declaration to `IList`. This breaks the code in a very unexpected manner, because then the function `IEnumerable Reverse(this IEnumerable source)` overload is used, and this goes unnoticed - you would have to watch for unused return value, and that is rarely practiced in C# – Cee McSharpface Oct 21 '16 at 15:56
128

One workaround would be Return NavItems.AsEnumerable().Reverse();

Mafu Josh
  • 2,523
  • 1
  • 23
  • 25
22

.Reverse() on a list reverses the items within the list, it does not return a new reversed list.

Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144
10

Reverse() does not returns reversed list itself, it modifies original list. So rewrite it as following:

return NavItems.Reverse(); 

TO

NavItems.Reverse(); 
return NavItems;
sll
  • 61,540
  • 22
  • 104
  • 156
6

Reverse() does not return a List as expected of your function.

NavItems.Reverse();
return NavItems;
JK.
  • 5,126
  • 1
  • 27
  • 26
4

If you have a list like in your example:

List<Lite.CategoryNavItem> NavItems

You can use the generic Reverse<> extensions method to return a new list without modifiying the original one. Just use the extension method like this:

List<Lite.CategoryNavItem> reversed = NavItems.Reverse<Lite.CategoryNavItem>();

Notes: You need to specify the <> generic tags to explicit use the extension method. Don't forget the

using System.Linq;
MLH
  • 149
  • 2
  • 4
  • I think there is a .ToList() missing at the end. List reversed = NavItems.Reverse().ToList(); – nogood Nov 14 '21 at 22:43
3

I had a situation where none of the suggested options suited me. So, if you:

  • don't want to use someList.Reverse() because it returns nothing (void)
  • don't want to use someList.Reverse() because it modifies source list
  • use someList.AsEnumerable().Reverse() and get the Ambiguous invocation error

You can try Enumerable.Reverse(someList) instead.

Don't forget the:

using System.Linq;
Bodix
  • 404
  • 5
  • 7
3

.Reverse reverses the "in-place"..., try

NavItems.Reverse();
return NavItems;
Yahia
  • 69,653
  • 9
  • 115
  • 144