映射到另一个值的枚举项

本文关键字:枚举 另一个 映射 | 更新日期: 2023-09-27 18:28:14

我有枚举:

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方法。

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

所以。。

对于这个问题,还有什么更优雅的解决方案吗?

谢谢:-)

映射到另一个值的枚举项

四个选项:

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

    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" },        
    };
    

    当然,您需要处理方法中的默认值。

  • 使用资源文件,每个字符串表示形式都有一个条目。如果你真的试图以一种可能需要针对不同文化进行不同翻译的方式翻译,这会更好。

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

[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;
}

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

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

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

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

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

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
} 

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