C# Getting Enum values

后端 未结 11 1178
深忆病人
深忆病人 2020-12-12 15:25

I have a enum containing the following (for example):

  • UnitedKingdom,
  • UnitedStates,
  • France,
  • Portugal

In my code I use

11条回答
  •  粉色の甜心
    2020-12-12 15:40

    You can't assign an enum value to a string to start with. You'd have to call ToString(), which would convert Country.UnitedKingdom to "UnitedKingdom".

    Two options suggest themselves:

    • Create a Dictionary
    • A switch statement
    • Decorate each value with an attribute, and load that with reflection

    Comments about each of them...

    Sample code for Dictionary

    using System;
    using System.Collections.Generic;
    
    enum Country
    {
        UnitedKingdom, 
        UnitedStates,
        France,
        Portugal
    }
    
    class Test
    {
        static readonly Dictionary CountryNames =
            new Dictionary
        {
            { Country.UnitedKingdom, "UK" },
            { Country.UnitedStates, "US" },
        };
    
        static string ConvertCountry(Country country) 
        {
            string name;
            return (CountryNames.TryGetValue(country, out name))
                ? name : country.ToString();
        }
    
        static void Main()
        {
            Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
            Console.WriteLine(ConvertCountry(Country.UnitedStates));
            Console.WriteLine(ConvertCountry(Country.France));
        }
    }
    

    You might want to put the logic of ConvertCountry into an extension method. For example:

    // Put this in a non-nested static class
    public static string ToBriefName(this Country country) 
    {
        string name;
        return (CountryNames.TryGetValue(country, out name))
            ? name : country.ToString();
    }
    

    Then you could write:

    string x = Country.UnitedKingdom.ToBriefName();
    

    As mentioned in the comments, the default dictionary comparer will involve boxing, which is non-ideal. For a one-off, I'd live with that until I found it was a bottleneck. If I were doing this for multiple enums, I'd write a reusable class.

    Switch statement

    I agree with yshuditelu's answer suggesting using a switch statement for relatively few cases. However, as each case is going to be a single statement, I'd personally change my coding style for this situation, to keep the code compact but readable:

    public static string ToBriefName(this Country country) 
    {
        switch (country)
        {
            case Country.UnitedKingdom:  return "UK";
            case Country.UnitedStates:   return "US";
            default:                     return country.ToString();
        }
    }
    

    You can add more cases to this without it getting too huge, and it's easy to cast your eyes across from enum value to the return value.

    DescriptionAttribute

    The point Rado made about the code for DescriptionAttribute being reusable is a good one, but in that case I'd recommend against using reflection every time you need to get a value. I'd probably write a generic static class to hold a lookup table (probably a Dictionary, possibly with a custom comparer as mentioned in the comments). Extension methods can't be defined in generic classes, so you'd probably end up with something like:

    public static class EnumExtensions
    {
        public static string ToDescription(this T value) where T : struct
        {
            return DescriptionLookup.GetDescription(value);
        }
    
        private static class DescriptionLookup where T : struct
        {
            static readonly Dictionary Descriptions;
    
            static DescriptionLookup()
            {
                // Initialize Descriptions here, and probably check
                // that T is an enum
            }
    
            internal static string GetDescription(T value)
            {
                string description;
                return Descriptions.TryGetValue(value, out description)
                    ? description : value.ToString();
            }
        }
    }
    

提交回复
热议问题