使用友好名称转换为enum和从enum转换

时间:2018-04-21 18:54:08

标签: c# generics inheritance enums

我经常遇到需要从用户友好/描述字符串中解析的枚举的情况。稍后,需要将相同的枚举转换为用户友好的字符串。我试图想出一种概括这段代码的方法,这样我就可以轻松添加新的枚举定义,而无需重复转换代码。这是我到目前为止所提出的,但我仍然不喜欢它。我仍然需要在每个派生类中重复两行代码(IdToName和NameToId调用)。有没有办法可以修改它,所以在派生类中不再有重复(所有转换函数只在基类中定义):

这是我的基类:

public class DictionaryEnum
{
    public static T NameToId<T>(Dictionary<T, string> idToNames, string name, T defaultValue)
    {
        foreach (var idToName in idToNames)
        {
            if (string.Compare(idToName.Value, name, StringComparison.CurrentCultureIgnoreCase) == 0)
                return idToName.Key;
        }

        return defaultValue;
    }

    public static string IdToName<T>(Dictionary<T, string> idToNames, T id, T defaultValue)
    {
        if (!idToNames.ContainsKey(id))
            id = defaultValue;

        return idToNames[id];
    }
}

这是第一个枚举示例:

public class AttachmentType : DictionaryEnum
{
    public enum Id
    {
        Undefined = 1,
        CameraImage = 2,
        AlbumImage = 3,
        Video = 4,
        Audio = 5,
    }

    private static readonly Dictionary<Id, string> _idToNames = new Dictionary<Id, string>
    {
        { Id.Undefined, "N/A" },
        { Id.CameraImage, "Camera Image" },
        { Id.AlbumImage, "Album Image" },
        { Id.Video, "Video" },
        { Id.Audio, "Audio" },
    };

    public static Id NameToId(string name) => NameToId(_idToNames, name, Id.Undefined);
    public static string IdToName(Id id) => IdToName(_idToNames, id, Id.Undefined);
}

这是第二个枚举示例:

public class TestStatus : DictionaryEnum
{
    public enum Id
    {
        Undefined = 0,
        Opened = 1,
        Started = 2,
        Closed = 3,
    };

    private static readonly Dictionary<Id, string> _idToNames = new Dictionary<Id, string>
    {
        { Id.Undefined, "is_undefined" },
        { Id.Opened, "is_opened" },
        { Id.Started, "is_started" },
        { Id.Closed, "is_closed" },
    };

    public static Id NameToId(string name) => NameToId(_idToNames, name, Id.Undefined);
    public static string IdToName(Id id) => IdToName(_idToNames, id, Id.Undefined);
}

1 个答案:

答案 0 :(得分:1)

所有感觉太吵......

几年前我遇到了类似的需求并使用了以下解决方案。 使用enum装饰DescriptionAttribute并将描述性文字放在那里。像这样:

public enum Id
{
    [Description("Undefined")]
    Undefined = 1,

    [Description("Camera Image")]
    CameraImage = 2,

    [Description("Album Image")]
    AlbumImage = 3,

    [Description("Video Image")]
    Video = 4,

    [Description("Audio")]
    Audio = 5,
}

接下来,实现一个接受枚举并检索自定义Description属性的扩展方法。

public static class EnumExtensions
{
    public static string GetDescription<TEnum>(this TEnum value)
        where TEnum : struct, IConvertible // Enums do implement IConvertible
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("TEnum is not an enum type :(");
        }

        var et = typeof(TEnum);
        var name = Enum.GetName(et, value);

        result = et.GetField(name)
            ?.GetCustomAttributes(false)
            ?.OfType<DescriptionAttribute>()
            ?.FirstOrDefault()
            .Description
        ;

        return result;
    }
}

享受。