是否可以按类型循环枚举?
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()){
}
我正在从枚举中制作几个下拉列表。例如,午餐时间枚举的长度将添加这样的下拉列表项:
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()){
}