5
\$\begingroup\$

Due to the fact that Entity does not support Enums, I am converting them to strings, string lists, and back again.

The reason is two fold: type-safety, and consistency in the database.

Now, I have a bunch of these, but I will use Credit Cards as an example:

    public enum CreditCardName
    {
        VISA,
        Master_Card,
        Discover,
        American_Express
    }

Originally, I decided on writing the same method for them, over and over again:

    public static List<string> GetCreditCardTypes()
    {
        var list = Enum.GetNames(typeof(CreditCardName));
        return list.Select(n => n.Replace("_", " ")).ToList();
    }

Then it occurred to me that I could make one private method to do this:

    public static List<string> GetCreditCardTypes()
    {
        return EnumToList(typeof(CreditCardName));
    }


    private static List<string> EnumToList(Type type)
    {
        var list = Enum.GetNames(type);
        return list.Select(n => n.Replace("_", " ")).ToList();
    }

Now I'm also doing something similar in reverse, but will skip the code. The question I have is if this is a good way to go about this? I know there are other workarounds for Entity's lack of enum support, but they are a bit cumbersome for my simple needs. I have never used Types in this way, so I just wanted to check that this is how Type/typeof are intended to be used, and that this will not cause unforeseen runtime issues.

\$\endgroup\$
  • \$\begingroup\$ Are you talking about Entity Framework when talking about Entity? \$\endgroup\$ – IEatBagels Aug 8 '14 at 17:52
9
\$\begingroup\$

I solved a similar issue by inventing a DisplayName attribute, so I can define my enums like this:

public enum CreditCardName
{
    [DisplayName("VISA")]
    Visa,

    [DisplayName("MasterCard")]
    MasterCard,

    [DisplayName("Discover")]
    Discover,

    [DisplayName("American Express")]
    AmericanExpress
}

This has a number of advantages. For one, apps like Resharper will stop complaining about your naming scheme. Also, your string doesn't have to actually correspond to an English name, it could correspond to an entry in a translation strings file or something like that.

Source for DisplayName:

[AttributeUsage(AttributeTargets.Field)]
public class DisplayName : Attribute
{
    public string Title { get; private set; }

    public DisplayName(string title)
    {
        this.Title = title;
    }
}

Source for the method to retrieve your DisplayName objects

        IEnumerable<DisplayName> attributes = from attribute in typeof(CreditCardName).GetCustomAttributes(true)
                                              let displayName = attribute as DisplayName
                                              where displayName != null
                                              select displayName;

You can roll this into a more complete generic method too:

public string[] GetNames<TEnum>()
{
    return (from attribute in typeof(CreditCardName).GetCustomAttributes(true)
                                                     let displayName = attribute as DisplayName
                                                     where displayName != null
                                                     select displayName.Title).ToArray();
}

Unfortuately, I there isn't a way you can enforce that TEnum is an enum at compile time, but you could make it throw an exception instead.

\$\endgroup\$
  • \$\begingroup\$ Wow, this is a much better solution! It solves issues I didn't even mention (you even caught the VISA/Visa one). But I had few other naming issues where underscores weren't cutting it. Thank you! \$\endgroup\$ – John Smith Jul 9 '11 at 7:22
  • 1
    \$\begingroup\$ Another issue that is solved by Rashkolnikov's solution is what happens if you ever decide to start making use of an obfuscator. \$\endgroup\$ – Mike Nakis Nov 28 '11 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.