【问题标题】:How to get the data value of an enum in a generic method?如何在泛型方法中获取枚举的数据值?
【发布时间】:2019-02-11 13:27:46
【问题描述】:

感谢this 的问题,我设法将我的通用方法限制为只接受枚举。

现在我正在尝试创建一个通用方法,以便我可以将下拉列表绑定到我选择的任何枚举,在下拉列表中显示描述,其值等于 numeric 枚举值的值。

public static object EnumToDataSource<T>() where T : struct, IConvertible {
  if (!typeof(T).IsEnum) // just to be safe
    throw new Exception(string.Format("Type {0} is not an enumeration.", typeof(T)));
  var q = Enum.GetValues(typeof(T)).Cast<T>()
    .Select(x => new { ID = DataUtil.ToByte(x), Description = x.ToString() }) // ToByte() is my own method for safely converting a value without throwing exceptions
    .OrderBy(x => x.Description);
  return q;
}

看起来不错,但 ToByte() 总是返回 0,即使我的枚举有明确设置的值,如下所示:

public enum TStatus : byte {
  Active = 1,
  Inactive = 0,
}

在通用方法之外,如果我将TStatus 类型的值转换为byte,它可以完美运行。在泛型方法中,如果我尝试将T 类型的某些内容转换为byte,则会出现编译器错误。 我在 Enum 静态接口中也找不到任何东西来执行此操作。

那么,如何在泛型中获取枚举的数值? (我也会感激地接受任何其他关于优化我的代码的建议......)

编辑: 嗯,呃……原来这东西不起作用……因为我的 ToByte() 方法中有一个错误……(脸红)。哦,好吧,无论如何,谢谢 - 我从中学到了很多东西!

【问题讨论】:

  • Convert.ToByte() 或 Enum.Parse( typeof(T), tVal.ToString() ) 应该可以正常工作。

标签: c# linq generics enums


【解决方案1】:

我认为最简单的做法是使用 Convert 类而不是强制转换:

T someValueThatIsAnEnum;
byte enumValue = Convert.ToByte( (object)someValueThatIsAnEnum );

或者,您可以依赖枚举可以将自己转换为字符串表示,并将自己解析回来这一事实:

T someValueThatIsAnEnum;
string enumAsString = someValueThatIsAnEnum.ToString();
byte enunValue = (byte)Enum.Parse( typeof(T), enumAsString );

【讨论】:

    【解决方案2】:

    您可以这样做(将 DataUtil.ToByte(x) 更改为 x.ToByte(null)):

    public static object EnumToDataSource<T>() where T : struct, IConvertible
            {
                if (!typeof (T).IsEnum) throw new Exception(string.Format("Type {0} is not an enumeration.", typeof (T)));
                var q =
                    Enum.GetValues(typeof (T)).Cast<T>().Select(x => new {ID = x.ToByte(null), Description = x.ToString()}).OrderBy(
                        x => x.Description).ToArray();
                return q;
            }
    

    【讨论】:

      【解决方案3】:

      我使用以下实用函数将枚举类型转换为可绑定的哈希表。它还将骆驼大小写名称正则表达式以空格分隔的单词。

      public static Hashtable BindToEnum(Type enumType)
      {
          // get the names from the enumeration
          string[] names = Enum.GetNames(enumType);
          // get the values from the enumeration
          Array values = Enum.GetValues(enumType);
          // turn it into a hash table
          Hashtable ht = new Hashtable(names.Length);
      
          for (int i = 0; i < names.Length; i++)
              // Change Cap Case words to spaced Cap Case words
              // note the cast to integer here is important
              // otherwise we'll just get the enum string back again
              ht.Add(
                  (int)values.GetValue(i),
                  System.Text.RegularExpressions.Regex.Replace(names[i], "([A-Z0-9])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim()
                  );
          // return the dictionary to be bound to
          return ht;
      }
      

      您可以轻松地将其调整为通用函数,只需将您在问题中提出的内容放在首位并更改函数的定义。

      【讨论】:

        【解决方案4】:

        也许你可以用我的EnumExtensions做点什么

        foreach 枚举并创建数据源。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多