【问题标题】:Get underlying value of a generic Enum获取通用枚举的基础值
【发布时间】:2013-06-18 10:10:11
【问题描述】:

我想为给定的泛型Enum 类型生成基础值和名称的列表。我想要原生基础值(如objects)。

    public static ReadOnlyCollection<EnumerationMember> ListFromEnum<TEnum>()
    {
        Type enumType = typeof(TEnum);
        if (!enumType.IsEnum)
        {
            throw new InvalidOperationException("TEnum is not an enum");
        }

        Type underlyingType = Enum.GetUnderlyingType(enumType);
        TEnum[] enumValues = (TEnum[])Enum.GetValues(enumType);

        return enumValues
            .Select(ev => new EnumerationMember(
                (???)ev,
                EnumerationExtension.GetDescription(enumType, ev)))
            .ToList()
            .AsReadOnly();
    }

    public class EnumerationMember
    {
        public EnumerationMember(object value, string description)
        {
            this.Value = value;
            this.Description = description;
        }

        public object Value { get; private set; }

        public string Description { get; private set; }
    }

【问题讨论】:

    标签: c# .net generics types enums


    【解决方案1】:

    最简单的:

    .Select(ev => Convert.ChangeType(ev, underlyingType))
    

    但我的偏好是返回一个正确类型的数组 - 你甚至不需要转换步骤:

    public static Array ListValuesFromEnum<T>()
    {
        Type enumType = typeof(T);
        Type underlyingType = Enum.GetUnderlyingType(enumType);
        Array enumValues = Enum.GetValues(enumType);
    
        var arr = Array.CreateInstance(underlyingType, enumValues.Length);
        enumValues.CopyTo(arr, 0);
        return arr;
    }
    

    【讨论】:

    • 我考虑过,但我不知道它是通过常规转换函数运行它还是只是在内部将其转换为底层类型。有什么方法可以使用 Type 显式执行强制转换,还是一样?
    • @Kurian 好吧,我检查了一下,它似乎工作 - 盒装值输入为short(等),而不是SomeEnum。顺便说一句,我个人会尝试返回一个short[](通过Array 作为方法的返回类型),但这只是我;代码并没有太大的不同。
    • @Kurian 哦,发现如果您使用右类型数组方法,内置的保值转换会自动处理它 - 请参阅编辑
    • 我更新了我的问题,因为您的回答虽然正确,但并不直接适用于我的问题。
    【解决方案2】:

    这里有一些工作代码,它使用Convert.ChangeType

    public static ReadOnlyCollection<EnumerationMember> ListValuesFromEnum<T>()
    {
        Type enumType = typeof(T);
        Type underlyingType = Enum.GetUnderlyingType(enumType);
        T[] enumValues = (T[])Enum.GetValues(enumType);
    
        return enumValues
            .Select(ev => new EnumerationMember(Convert.ChangeType(ev,underlyingType), ev.ToString()))
            .ToList()
            .AsReadOnly();
    }        
    

    这是一个现场演示:http://rextester.com/EHOE12097

    【讨论】:

    • 这甚至适用于我更新的问题,但我对比 Convert.ChangeType 更有效的方法感兴趣。
    • 高效的方法?这种方法有什么特别低效的地方吗?
    • 我不确定它是简单地在内部执行转换还是通过一些转换函数运行它。
    • 所以你不知道这是否有效,你只是在猜测。如果您没有效率基准,我该如何回答您的问题?
    • 我基于上一个答案中隐含的提高效率。
    猜你喜欢
    • 1970-01-01
    • 2016-11-30
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多