枚举项映射到另一个值

时间:2013-08-20 07:21:01

标签: c#

我有枚举:

enum MyEnum{
    aaaVal1,
    aaaVal2,
    aaaVal3,
}  

我需要缩写版本的' MyEnum'它映射了来自' MyEnum'不同的价值观。我目前的方法是简单翻译每个项目的方法:

string translate(MyEnum myEnum)
{
    string result = "";
    switch ((int)myEnum)
    {
        0:   result = "abc";
        1:   result = "dft";
        default: result = "fsdfds"
    }
    return result;
}

这种方法的问题是,每次程序员更改MyEnum时,他也应该更改translate方法。

这不是一种好的编程方式。

所以......

这个问题还有更优雅的解决方案吗?

谢谢: - )

4 个答案:

答案 0 :(得分:9)

四个选项:

  • 使用属性装饰您的枚举值,例如

    enum MyEnum
    {
        [Description("abc")]
        AaaVal1,
        [Description("dft")]
        AaaVal2,
        AaaVal3,
    } 
    

    然后你可以通过反射创建一个映射(如下面的字典解决方案)。

  • 保留switch语句但是为了更好的可读性而打开枚举值而不是数字:

    switch (myEnum)
    {
        case MyEnum.AaaVal1: return "abc";
        case MyEnum.AaaVal2: return "dft";
        default:             return "fsdfds";
    }
    
  • 创建Dictionary<MyEnum, string>

    private static Dictionary<MyEnum, string> EnumDescriptions = 
        new Dictionary<MyEnum, string>
    {
        { MyEnum.AaaVal1, "abc" },
        { MyEnum.AaaVal2, "dft" },        
    };
    

    当然,你需要处理方法中的违约。

  • 使用资源文件,每个字符串表示都有一个条目。如果您真的想要以不同文化需要不同翻译的方式翻译,那会更好。

答案 1 :(得分:2)

考虑到在枚举上使用描述符非常普遍,这里有一个足够好的类:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
class EnumDescriptor : Attribute
{
    public readonly string Description;

    public EnumDescriptor(string description)
    {
        this.Description = description;
    }

    public static string GetFromValue<T>(T value) where T : struct
    {
        var type = typeof(T);
        var memInfo = type.GetField(value.ToString());
        var attributes = memInfo.GetCustomAttributes(typeof(EnumDescriptor), false);

        if (attributes.Length == 0)
        {
            return null;
        }

        return ((EnumDescriptor)attributes[0]).Description;
    }
}

enum MyEnum
{
    [EnumDescriptor("Hello")]
    aaaVal1,
    aaaVal2,
    aaaVal3,
}  

string translate(MyEnum myEnum)
{
    // The ?? operator returns the left value unless the lv is null,
    // if it's null it returns the right value.
    string result = EnumDescriptor.GetFromValue(myEnum) ?? "fsdfds";
    return result;
}

答案 2 :(得分:1)

我发现你想要做的事有点奇怪。

如果您正在翻译,那么您应该创建一个RESX文件并创建实际翻译。

但是为了回答你的问题,我猜你可以用相同数量的字段和相同的编号创建另一个enum(如果你使用的是默认值以外的任何东西),并将其作为缩写名称。将一个连接到另一个应该很简单:

string GetAbbreviation(Enum1 enum1)
{
  return ((Enum2)((int)enum1)).ToString();
}

答案 3 :(得分:1)

对于这种情况,属性将是很好的解决方案。您可以通过声明方式为枚举成员指定翻译:

public class TranslateAttribute
{
    public string Translation { get; private set; }

    public TranslateAttribute(string translation)
    {
        Translation = translation;
    }
}

enum MyEnum
{
    [Translate("abc")]
    aaaVal1,

    [Translate("dft")]
    aaaVal2,

    [Translate("fsdfds")]
    aaaVal3
} 

在此之后,您应该编写获得翻译的常用方法。它应该通过翻译检查属性(通过反射)并在指定时返回翻译,在其他情况下返回默认值。