2

我正在寻找一个将枚举转换为字典列表的函数。枚举名称也将被转换为更易于阅读的形式。我只想调用函数,提供枚举类型,然后取回字典。我相信我快到了我似乎无法弄清楚如何将枚举转换为正确的类型。(在“returnList.Add”行上出现错误)。现在我只是使用 var 作为类型,但是我知道类型,因为它是传入的。

internal static Dictionary<int,string> GetEnumList(Type e)
{
    List<string> exclusionList =
    new List<string> {"exclude"};

    Dictionary<int,string> returnList = new Dictionary<int, string>();

    foreach (var en in Enum.GetValues(e))
    {
        // split if necessary
        string[] textArray = en.ToString().Split('_');

        for (int i=0; i< textArray.Length; i++)
        {
            // if not in the exclusion list
            if (!exclusionList
                .Any(x => x.Equals(textArray[i],
                    StringComparison.OrdinalIgnoreCase)))
            {
                textArray[i] = Thread.CurrentThread.CurrentCulture.TextInfo
                    .ToTitleCase(textArray[i].ToLower());
            }
        }

        returnList.Add((int)en, String.Join(" ", textArray));
    }

    return returnList;
}
4

3 回答 3

6

您可以使用通用方法,该方法将使用枚举值和名称创建字典:

public static Dictionary<int, string> GetEnumList<T>()
{
    Type enumType = typeof(T);
    if (!enumType.IsEnum)
        throw new Exception("Type parameter should be of enum type");

    return Enum.GetValues(enumType).Cast<int>()
               .ToDictionary(v => v, v => Enum.GetName(enumType, v));
}

随意根据需要修改默认枚举名称。用法:

var daysDictionary = Extensions.GetEnumList<DayOfWeek>();
string monday = daysDictionary[1];
于 2013-09-17T16:48:07.317 回答
4

有时是使用 enum 和描述的更好方法,并通过泛型方法获取 Dictonary(EnumValue, EnumValueDescription)。当我需要在下拉列表中查看过滤器时,我会使用它。您可以将它用于代码中的任何枚举。

例如:

public static class EnumExtensions
{
    public static string GetDescription(this Enum value)
    {
        Type type = value.GetType();
        string name = Enum.GetName(type, value);
        if (name != null)
        {
            FieldInfo field = type.GetField(name);
            if (field != null)
            {
                var attr = Attribute.GetCustomAttribute(field, typeof (DescriptionAttribute)) as DescriptionAttribute;
                if (attr != null)
                {
                    return attr.Description;
                }
            }
        }
        return value.ToString();
    }

    public static Dictionary<T, string> EnumToDictionary<T>()
    {
        var enumType = typeof(T);

        if (!enumType.IsEnum)
            throw new ArgumentException("T must be of type System.Enum");

        return Enum.GetValues(enumType)
                   .Cast<T>()
                   .ToDictionary(k => k, v => (v as Enum).GetDescription());
    }
}

呼叫看起来像这样:

public static class SomeFilters
{
    public static Dictionary<SomeUserFilter, string> UserFilters = EnumExtensions.EnumToDictionary<SomeUserFilter>();
}

对于枚举:

public enum SomeUserFilter
{
    [Description("Active")]
    Active = 0,

    [Description("Passive")]
    Passive = 1,

    [Description("Active & Passive")]
    All = 2
}
于 2014-05-16T19:29:49.360 回答
1

请注意,在 C# 中使用枚举定义的类型可以具有多种基础类型(字节、sbyte、short、ushort、int、uint、long、ulong),如文档所述:enum。这意味着并非所有枚举值都可以安全地转换为 int 并在不抛出异常的情况下离开。

例如,如果您希望进行概括,您可以安全地将所有枚举值转换为浮点数(虽然很奇怪,但它涵盖了隐式数字转换表所告诉的任何枚举基础类型)。或者您可以通过泛型请求特定的底层类型。

这两种解决方案都不是完美的,尽管两者都能通过充分的参数验证安全地完成工作。泛化到浮点值解决方案:

static public IDictionary<float, string> GetEnumList(Type enumType)
{
    if (enumType != null)
        if (enumType.IsEnum)
        {
            IDictionary<float, string> enumList = new Dictionary<float, string>();

            foreach (object enumValue in Enum.GetValues(enumType))
                enumList.Add(Convert.ToSingle(enumValue), Convert.ToString(enumValue));

            return enumList;
        }
        else
            throw new ArgumentException("The provided type is not an enumeration.");
    else
        throw new ArgumentNullException("enumType");
}

通用参数解决方案:

static public IDictionary<EnumUnderlyingType, string> GetEnumList<EnumUnderlyingType>(Type enumType)
{
    if (enumType != null)
        if (enumType.IsEnum && typeof(EnumUnderlyingType) == Enum.GetUnderlyingType(enumType))
        {
            IDictionary<EnumUnderlyingType, string> enumList = new Dictionary<EnumUnderlyingType, string>();

            foreach (object enumValue in Enum.GetValues(enumType))
                enumList.Add((EnumUnderlyingType)enumValue, enumValue.ToString());

            return enumList;
        }
        else
            throw new ArgumentException("The provided type is either not an enumeration or the underlying type is not the same with the provided generic parameter.");
    else
        throw new ArgumentNullException("enumType");
}

或者您可以将其中之一与lazyberezovsky 的解决方案结合使用,以避免空值检查。或者通过使用隐式转换来更好地提供提供的解决方案(假设您有一个具有底层类型 char 的枚举,您可以安全地将一个 char 转换为一个 int 意味着该方法,如果需要返回一个 int 键的字典是具有提供的枚举值底层类型是 char 的枚举应该可以正常工作,因为在 int 上存储 char 没有问题)。

于 2013-09-17T17:55:27.627 回答