5

我有枚举:

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

4 回答 4

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

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

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

于 2013-08-20T07:26:11.800 回答
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;
}
于 2013-08-20T07:26:03.243 回答
1

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

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

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

string GetAbbreviation(Enum1 enum1)
{
  return ((Enum2)((int)enum1)).ToString();
}
于 2013-08-20T07:29:44.463 回答
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
} 

在此之后,您应该编写获取翻译的通用方法。它应该检查带有翻译的属性(通过反射),如果指定了翻译,则返回翻译,在其他情况下返回默认值。

于 2013-08-20T07:39:33.287 回答