无法转换类型' TEnum'到' int'

时间:2015-11-17 11:20:32

标签: c# linq enums

我尝试将枚举转换为List,如this示例中所述 e.g。

Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(v => new SelectListItem {
    Text = v.ToString(),
    Value = ((int)v).ToString()
}).ToList();

这项工作,但我想修改它以使用通用枚举

public static List<SelectListItem> GetEnumList<TEnum>(TEnum value)
{

        return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(v => new SelectListItem
        {
            Text = v.ToString(),
            Value = ((int)v).ToString()
        }).ToList();
 }

但是上面的代码没有编译并给出

  

无法转换类型&#39; TEnum&#39;到&#39; int&#39;

为行

  Value = ((int)v).ToString()
  1. 如何修复上述代码。

  2. 为什么它给出了通用枚举的编译错误,而不是正常的枚举

  3. 编辑:我已经尝试了线程中的建议但是我得到了进一步的错误:

    这是我的完整代码:

    public static IHtmlContent EnumDropDownListFor<TModel, TResult,TEnum>(
        this IHtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TResult>> expression,
        TEnum enumValue,
        string optionLabel) 
    {
        return htmlHelper.DropDownListFor(expression, (IEnumerable<SelectListItem>)GetEnumList(enumValue), optionLabel);
    }
    
    public static List<SelectListItem> GetEnumList<TEnum>(TEnum value) 
    {
        return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(v => new SelectListItem
        {
            Text = v.ToString(),
            Value = Convert.ToInt32(v).ToString()
        }).ToList();
    
    }
    

    但是我收到了运行时错误

      

    ArgumentException:提供的类型必须是Enum。

         

    参数名称:enumType

    就行了

    return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(v => new SelectListItem
        {
            Text = v.ToString(),
            Value = Convert.ToInt32(v).ToString()
        }).ToList();
    

    我需要在代码中修复哪些内容才能获得运行时错误。

4 个答案:

答案 0 :(得分:5)

您已经告诉编译器TEnum没有任何内容。就其而言,它可以是字符串,DateTime,BankAccount,Bullet或任何东西。

要实现这一点,您可以使用Enum.ParseConvert.ToInt32

UPD:我只需格式化注释中的代码并修复SO-copy-pasters的编译错误:D

public static int GetEnumIntValue<T>(T value)
    where T : struct
{
    Type genericType = typeof(T);
    Debug.Assert(genericType.IsEnum);
    Enum enumValue = Enum.Parse(genericType, value.ToString()) as Enum;
    return Convert.ToInt32(enumValue);
}

答案 1 :(得分:2)

您不需要值,只需要枚举类型。你可以使用这样的东西

通用

public static List<SelectListItem> GetEnumList<TEnum>()
    where TEnum : struct, IConvertible, IFormattable
{
    return ((TEnum[])Enum.GetValues(typeof(TEnum))).Select(v => new SelectListItem
    {
        Text = v.ToString(),
        Value = v.ToString("d", null)
    }).ToList();
}

非通用

public static List<SelectListItem> GetEnumList(Type enumType)
{
    return Enum.GetValues(enumType).Cast<IFormattable>().Select(v => new SelectListItem
    {
        Text = v.ToString(),
        Value = v.ToString("d", null)
    }).ToList();
}

这两种方法都不是编译类型安全的。通用,因为缺乏enum connstraint。非泛型 - 嗯,它类似于Enum静态方法,无论如何都不是编译类型安全的。如果使用非枚举类型调用,这两种方法都将抛出运行时异常。

答案 2 :(得分:1)

public static List<SelectListItem> GetEnumList<TEnum>(TEnum value) where TEnum : IConvertible
{
    return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(v => new SelectListItem
    {
        Text = v.ToString(),
        Value = v.ToInt32(null).ToString()
    }).ToList();
}
  1. Complier知道您在.Cast<MyEnum>()之后使用枚举类型。
  2. 但在.Cast<TEnum>()编译器之后并不知道可以的类型。

答案 3 :(得分:1)

编译器抱怨因为泛型方法中的类型参数不受约束

方法也不一定是通用的

public static List<SelectListItem> GetEnumList(Enum value)
{
    return Enum.GetValues(value.GetType())
            .Cast<Enum>()
            .Select(v => new SelectListItem
                        {
                            Text = v.ToString(),
                            Value = Convert.ToInt32(v).ToString()
                        })
            .ToList();
}
如果枚举的基础类型不是int

,那么

仍然可能是个问题

public enum LongEnum: ulong
{
    A = 0,
    B = 3000000000
}

// Run-time exception: Value was either too large or too small for an Int32.