Jacek Wojcik
Jacek Wojcik

Reputation: 1253

Enum item mapped to another value

I have enum:

enum MyEnum{
    aaaVal1,
    aaaVal2,
    aaaVal3,
}  

I need to have abbreviated version of 'MyEnum' which maps every item from 'MyEnum' to different values. My current approach is method which simply translates every item:

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

the problem with this approach is that every time programmer changes MyEnum he should also change translate method.

This is not a good way of programming.

So..

Is there any more elegant solution for this problem?

Thank you :-)

Upvotes: 5

Views: 186

Answers (4)

xanatos
xanatos

Reputation: 111830

Considering that the use of descriptors on enums is quite common, here it's a good-enough class to do it:

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

Upvotes: 2

Shad
Shad

Reputation: 4464

Attributes will be nice solution for this case. You can specify translations for enumeration members via declarative way:

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
} 

After this you should write common method for obtaining translations. It should check attribute with translation (via reflection) and return translation if it was specified and default value in other cases.

Upvotes: 1

MBender
MBender

Reputation: 5650

I'm finding what you're trying to do a bit weird.

If you're making translations, then you should create a RESX file and create ACTUAL translations.

But to answer your question, I guess you could create another enum with the same amount of fields and same numbering (if you're using anything other than the default) and have that act as the abbreviated names. Connecting one to the other should be straightforward:

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

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499860

Four options:

  • Decorate your enum values with attributes, e.g.

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

    Then you can create a mapping (like the dictionary solution below) via reflection.

  • Keep the switch statement but switch on the enum value instead of a number for better readability:

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

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

    You'd need to handle the defaulting in the method, of course.

  • Use a resource file, with an entry for each string representation. This would be better if you're really trying to translate in a way that might need different translations for different cultures.

Upvotes: 9

Related Questions