0

I am making several drop down lists from enums. For example, the length of a lunchbreak enum will add dropdown list items like this:

foreach (LunchBreak type in Enum.GetValues(typeof(LunchBreak)))
{
    items.Add(new SelectListItem()
    {
       Text = SiteUtilities.GetEnumDescription(type),
       Value = ((int)type).ToString()
    });
}

Where my enum is in the form of:

public enum LunchBreak : int
{
    [Description("20 minutes paid")]
    Paid_20 = 0,

    [Description("20 minutes unpaid")]
    Unpaid_20 = 1
}

Is there a way to make that foreach loop generic so I can pass in typeof(LunchBreak) so I don't have to redo the code for all the other enums?

I tried writing it where I could just pass in LunchBreak but then it complained about me using the enum as a Type.

I tried to do an extension method like here so I could call something like LunchBreak.GetSelectListItems("Please select a lunch break...") and had a look at several posts like this: Create Generic method constraining T to an Enum but didn't really get what was going on

Extension attempt:

public static class EnumExtensions
{
    public static List<SelectListItem> GetSelectListItems<T>(string defaultValue) where T : struct, IConvertible
    {
        if (typeof(T).IsEnum)
        {
            List<SelectListItem> items = new List<SelectListItem>()
            {
                new SelectListItem()
                {
                    Text = defaultValue,
                    Value = string.Empty
                }
            };

            foreach (T item in Enum.GetValues(typeof(T)))
            {
                items.Add(new SelectListItem()
                {
                    Text = SiteUtilities.GetEnumDescription(item), // this line fails as item is expected to be of type Enum
                    Value = ((int)item).ToString()  // this line fails as I can't cast item as an int
                });
            }

            return items;
        }

        throw new ArgumentException("T must be an enumerated type"); 
    }
}
Community
  • 1
  • 1

4 Answers4

1

You're almost there. You need to cast it to object then to Enum. For casting to int, you can instead use Convert.ToInt32.

public static class EnumExtensions
{
    public static List<SelectListItem> GetSelectListItems<T>(string defaultValue) where T : struct, IConvertible
    {
        if (!typeof (T).IsEnum)
            throw new ArgumentException("T must be an enumerated type");

        List<SelectListItem> items = new List<SelectListItem>()
        {
            new SelectListItem()
            {
                Text = "Please select a lunch break...",
                Value = string.Empty
            }
        };

        foreach (T item in Enum.GetValues(typeof(T)))
        {
            items.Add(new SelectListItem()
            {
                Text = SiteUtilities.GetEnumDescription((Enum)(object)item),
                Value = Convert.ToInt32(item).ToString()
            });
        }

        return items;
    }
}

Note: You're not using the parameter defaultValue you may need to get rid of it and I believe SelectListItem.Value has to be int to make more sense.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
0

Something like this should do (I have no idea about the GetEnumDescription prototype - but it could simply expect an object and reflect it.):

 public static IEnumerable<SelectListItem> GetSelectListItems<T>(string defaultValue)
 {
      if(!typeof(T).IsEnum)
        throw new Exception("Not an enum");

      yield return new SelectListItem
      {
          Text = defaultValue,
          Value = string.Empty
      };

      foreach(var item in Enum.GetValues(typeof(T))
      {
           yield return new SelectListItem
           {
                Text = SiteUtilities.GetEnumDescription((Enum)item),
                Value = Convert.ChangeType(item, typeof(T).GetEnumUnderlyingType().ToString()) // not all enums are int's
           }
      }
 }

You can ToList() it with a wrapper if you need to.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
0

Here's a simple extension that I would build any 'enum looping' off of:

Extension

public static class EnumExtension
    {
        public static IEnumerable<T> GetValues<T>(this T e)
        {
            return Enum.GetValues(e.GetType()).Cast<T>();
        }
}

Usage

foreach(var t in new MyEnum().GetValues()){

}
BlackjacketMack
  • 5,472
  • 28
  • 32
-1

The code below works

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;


namespace ConsoleApplication28
{
    class Program
    {
        public enum LunchBreak : int
        {
            Paid_20 = 0,
            Unpaid_20 = 1,
        }
        static void Main(string[] args)
        {
            foreach (LunchBreak type in Enum.GetValues(typeof(LunchBreak)))
            {
                LunchBreak LunchItem = type;

            }

        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20