【问题标题】:Changing a method from converting just strings to strings and int将方法从仅将字符串转换为字符串和 int
【发布时间】:2013-01-03 13:20:34
【问题描述】:

请耐心等待,因为这对我来说是一个困难的概念。我有一个方法可以将enum 中的项目作为字符串返回(用于数据库存储)。方法如下:

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 存储在数据库中。

但是,GetItemsFromEnum 方法在我使用 [Flags] 的情况下不起作用,并且需要我更改它,以便在 GetItemsFromEnum 方法中分配的值不是 enum 的字符串值,这是int 值。

这实际上是一个两部分:

  1. 如何修改方法,使enumValue 成为 int 的值来自 enum [Flags](即,如果选择了“1 + 2” (两个复选框),那么保存的int 值将是“3”)?
  2. 最重要的是,我可以在方法中插入什么样的逻辑 这样我所有的其他enum(没有[Flags])都不是 受影响(即,它仍然转换ToString)?我在想一些if ... else 的逻辑,但是这样行吗?

【问题讨论】:

    标签: c# asp.net-mvc enums


    【解决方案1】:

    首先,[Flags] 属性不会为枚举值添加特殊属性,它只是在将其格式化为字符串时通过 Enum 类的反射使用,并让使用您的代码的人知道他们可以安全地对枚举使用按位运算,或者换句话说,不会产生不希望的结果。

    让我们来看看这个枚举:

    [Flags]
    enum MyEnum
    {
        Undefined,
        Employee,
        Student
    }
    

    让我们以这种方式创建一个变量:

    var employeeAndStudent = MyEnum.Employee | MyEnum.Student;
    

    如果转换为整数,变量等于 3。虽然ToString() 方法将打印“Employee, Student”,但Enum.GetNames 没有为字段 3 分配值——很明显,因为它没有名称。我可以想到两种解决方案:

    1. 您创建自己的GetNames,除了定义的名称外,它还会返回枚举值的所有可能组合,方便地以您的格式打印。

    2. 您在枚举中定义标志,如果有很多成员,这可能会变得非常浪费。在我们的例子中,MyEnum 会变成:

      [Flags]
      enum MyEnum
      {
          Undefined,
          Employee,
          Student,
          EmployeeAndStudent
      }
      

    还有一件事,你的方法似乎有一个错误。这一行:

    Selected = enumValue.Equals(selectedValue)
    

    正在尝试将枚举类型与字符串进行比较,并且总是会导致错误。你确定SelectListItem.Value 应该是string 类型吗?我建议你检查你的代码。

    直接回答您的问题:

    1. [Flags] 添加到您的枚举并使用 OR 运算符组合值。
    2. 在您的GetEnumDescription 方法中,检查该类型是否具有Flags 属性。

    【讨论】:

    • 在您的示例中,如果没有 Flags 属性,employeeAndStudent.ToString() 将返回“3”。它可能会改变枚举行为!
    • @knaki02 你说得对,我应该更具体一些,我会编辑我的帖子。
    • 感谢您的提示,但我对标志感到困惑。为什么要使用组合创建变量?我认为标志的重点是(假设 1、2、4、8、16、32、64)得到一个整数值,例如 106(这意味着选择了 2、8、32 和 64) .
    • @MEMoriarty 因为在您的情况下您调用Enum.GetNames,它不会返回您的字段可能(但未定义)组合的名称。如果你有一个只有 32 个字段的枚举,你的方法将返回超过 40 亿个字符串!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 2011-03-06
    • 1970-01-01
    • 2018-07-05
    相关资源
    最近更新 更多