如何在泛型方法中获取枚举的数据值?

时间:2009-07-23 14:32:34

标签: c# linq generics enums

感谢this问题,我设法解决了如何限制我的通用方法只接受枚举。

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

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()方法中有一个错误......(脸红)。哦,谢谢,无论如何 - 我从中学到了很多东西!

4 个答案:

答案 0 :(得分:3)

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

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

或者,您可以依赖以下事实:枚举可以将自身转换为字符串表示形式,并自行解析:

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

答案 1 :(得分: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;
        }

答案 2 :(得分:0)

我使用以下实用程序函数将枚举类型转换为可绑定的哈希表。它还将骆驼案例名称用于空格分隔词。

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

您可以通过在问题中添加顶部并更改函数的定义来轻松地将其调整为通用函数。

答案 3 :(得分:0)

也许你可以对我的EnumExtensions

做点什么

预告枚举并创建数据源。