2

Enum を辞書リストに変換する関数を作成しようとしています。Enum 名も、より人間が読める形式に変換されます。関数を呼び出して列挙型を指定し、辞書を取得したいだけです。列挙型を正しい型にキャストする方法がわかりません。(「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

説明付きの列挙型を使用し、一般的なメソッドを介して 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# で列挙型を使用して定義された型は、ドキュメントに記載されているように、さまざまな基になる型 (byte、sbyte、short、ushort、int、uint、long、ulong) を持つことができることに注意してください: enum。これは、すべての enum 値を安全に int にキャストして、例外がスローされることなく回避できるわけではないことを意味します。

たとえば、一般化したい場合は、すべての enum 値を float に安全にキャストできます (奇妙ですが、暗黙的な数値変換テーブルが示すように、基になるすべての enum 型をカバーします)。または、ジェネリックを介して特定の基になる型を要求できます。

どちらのソリューションも完全ではありませんが、適切なパラメーター検証により、どちらも安全に作業を完了できます。浮動小数点値ソリューションへの一般化:

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 のソリューションと組み合わせて使用​​して、null チェックを回避できます。または、暗黙的な変換を使用して提供されたソリューションを改善します (たとえば、基になる型 char の列挙型があるとします。char を int に安全に変換できます。つまり、int キーの辞書を返すように要求された場合、提供された列挙型の値であるメソッドを意味します)。基になる型が char である enum は、int に char を格納することに問題がないため、問題なく動作するはずです)。

于 2013-09-17T17:55:27.627 に答える