是否可以按类型循环枚举?

Is it possible to loop through an enum by type?

我正在从枚举中制作几个下拉列表。例如,午餐时间枚举的长度将添加这样的下拉列表项:

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

我的枚举形式为:

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

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

有没有办法使 foreach 循环通用,这样我就可以传入 typeof(LunchBreak),这样我就不必为所有其他枚举重做代码?

我试着把它写在我可以传入 LunchBreak 的地方,但后来它抱怨我使用枚举作为类型。

我尝试像这里那样做一个扩展方法,这样我就可以调用类似 LunchBreak.GetSelectListItems("Please select a lunch break...") 的东西,并查看了几篇这样的帖子:Create Generic method constraining T to an Enum 但并没有真正了解发生了什么

延期尝试:

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"); 
    }
}

你快到了。您需要将其转换为对象,然后再转换为 Enum。要转换为 int,您可以改用 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;
    }
}

注意:您没有使用参数 defaultValue,您可能需要删除它,我认为 SelectListItem.Value 必须是 int 才能更有意义。

应该做这样的事情(我不知道 GetEnumDescription 原型 - 但它可以简单地期待一个对象并反映它。):

 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
           }
      }
 }

如果需要,您可以 ToList() 使用包装器。

下面的代码有效

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;

            }

        }
    }
}

这是一个简单的扩展,我将构建任何 'enum looping' 关闭:

分机

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

用法

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

}