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

时间:2015-05-14 12:24:20

标签: c# enums extension-methods

我正在从枚举中创建几个下拉列表。例如,午休时间枚举的长度将添加下拉列表项,如下所示:

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

4 个答案:

答案 0 :(得分:1)

你几乎就在那里。您需要将其转换为对象,然后转换为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才能更有意义。

答案 1 :(得分:0)

这样的事情应该做(我不知道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()

答案 2 :(得分:0)

这是一个简单的扩展,我将构建任何'枚举循环':

<强>扩展

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()){

}

答案 3 :(得分:-1)

以下代码可以使用

System.Web.Fakes.dll