请原谅我,因为这对我来说是一个很难的概念。我有一个方法,将enum
中的项作为字符串返回(用于DB存储)。方法如下:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>
(T selectedValue = default(T)) where T : struct
{
return from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.
Parse(typeof(T), name, true))
select new SelectListItem
{
Text = GetEnumDescription(name, typeof(T)),
Value = enumValue,
Selected = enumValue.Equals(selectedValue)
};
}
(注意:GetEnumDescription
是类中的另一个方法,它使[Display(Name="")
文本在UI中显示友好的内容。)
对于单个选择输入(单选按钮,下拉),这工作得很好。但是,通过多选择(列表框,复选框列表),我正在考虑使用enum
[Flags]
属性作为int
存储在DB中。
然而,在我使用[Flags]
的情况下,GetItemsFromEnum
方法将不起作用,并要求我更改它,以便在GetItemsFromEnum
方法中分配的值不是enum
的字符串值,而是int
值。
这实际上是一个两部分:
- 我如何修改方法,使
enumValue
将是从enum
到[Flags]
的int
的值(即,如果选择"1 + 2")(两个复选框),那么保存的int
值将是"3")? - 最重要的是,我可以在方法中插入哪种逻辑所以我所有其他的
enum
(没有[Flags]
的)都不是受影响(即,它仍然转换ToString
)?我在想一些if ... else
逻辑,但这行得通吗?
首先,[Flags]
属性不会为枚举的值添加特殊属性,它只是通过反射由Enum
类在将其格式化为字符串时使用,并让使用您的代码的人知道他们可以安全地在枚举上使用按位操作,或者换句话说,没有不想要的结果。
让我们取这个enum:
[Flags]
enum MyEnum
{
Undefined,
Employee,
Student
}
让我们这样创建一个变量:
var employeeAndStudent = MyEnum.Employee | MyEnum.Student;
如果转换为整型,则该变量等于3。虽然ToString()
方法将打印"Employee, Student",但Enum.GetNames
没有为字段3分配值——很明显,因为它没有名称。我能想到两个解决办法:
您可以创建自己的
GetNames
,除了已定义的名称外,还将返回枚举值的所有可能组合,方便地以您的格式打印。在枚举中定义标志,如果有许多成员,这可能会变得非常浪费。在本例中,
MyEnum
将变成:[Flags] enum MyEnum { Undefined, Employee, Student, EmployeeAndStudent }
还有一件事,你的方法似乎有一个bug。这条线:
Selected = enumValue.Equals(selectedValue)
试图将枚举类型与字符串类型进行比较,结果总是为false。你确定SelectListItem.Value
应该是string
类型吗?我建议你检查一下你的代码。
直接回答你的问题:
- 将
[Flags]
添加到枚举中,并使用OR操作符组合值。 - 在您的
GetEnumDescription
方法中,检查类型是否具有Flags
属性。