-1

I have a model like this.

 public class MenuItem
 {
      public string Description { get; set; }
      public string MenuTypeID { get; set; }
      public int DailyMax { get; set; }
 }

Then I have a method like this.

public List<MenuItem> GetMenuItem()
{
        List<MenuItem> menuItems = new List<MenuItem>();

        DataSet ds = null;
       .... left out ds populating code....

        try
        {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    MenuItem menuItem = new MenuItemType();

                    menuItem.Description = dr["Description"].ToString();
                    menuItem.MenuTypeID = dr["MenuTypeID"].ToString();

                    menuItems.Add(menuItem);
                }

            List<MenuItemType> SortedList = menuItems.Sort((x, y) => x.MenuTypeID.CompareTo(y.MenuTypeID));
            // compile error: Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<MenuItem>'
        }
        catch (Exception ex)
        {

        }
        finally
        {

        }

        return SortedList;
    }

My questions are,

  1. How to sort without the compile error?
  2. Is it possible to sort first by menuTypeId, then the description?
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
Prosper
  • 98
  • 1
  • 13
  • 1
    https://stackoverflow.com/questions/3309188/how-to-sort-a-listt-by-a-property-in-the-object also here is another https://stackoverflow.com/questions/289010/c-sharp-list-sort-by-x-then-y – TheGeneral Jan 12 '21 at 06:45
  • 1
    `List SortedList = menuItems.Sort` `Sort` doesn't _return_ a list. It _sorts an existing one_. – mjwills Jan 12 '21 at 07:17

2 Answers2

4
List<MenuItemType> SortedList = menuItems.Sort((x, y) => x.MenuTypeID.CompareTo(y.MenuTypeID));
// compile error: Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<MenuItem>'

The Sort method sorts the current List<> instance in place, and its return type is void. So you should just use:

menuItems.Sort((x, y) => x.MenuTypeID.CompareTo(y.MenuTypeID));

and after that, the same list menuItems will be sorted in the desired way.


To address the part about sorting by two properties, the lambda becomes a bit uglier:

menuItems.Sort((x, y) =>
{
  var c = x.MenuTypeID.CompareTo(y.MenuTypeID);
  if (c != 0)
    return c;
  return x.Description.CompareTo(y.Description);
});

Another possibility is to let the underlying type (class or struct) MenuItemType implement the interface IComparable<MenuItemType>. The implementation will look like the portion between { and } above. Then you can simply do:

menuItems.Sort();

This possibility is best if the MenuItemType is "naturally" sortable in this way in all situations.

The last possibility, to use LINQ, can be seen in Salah Akbari's answer. Note that with that method, a new List<> is created, and the original List<> remains unchanged. You do not care about this in your example because the original list is created as new List<...> in the same method, and is not kept (saved) or used later. But in other contexts, it may be an advantage (or a problem) that the original List<> (to which other variables or objects may hold references) is unchanged.

In extreme cases where the List<> is really long (not in your example, I am sure), note that .Sort will be faster than LINQ's OrderBy and ThenBy.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
0

You can use the OrderBy and ThenBy methods:

var sortedList = menuItems.OrderBy(o => o.menuTypeId).ThenBy(c => c.Description).ToList();
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109