简体   繁体   中英

Best way to structure static constant classes with common methods

I have a bunch of Constant Classes which I require to be static (see an example below)

public class FuelTypeConstant
    {
        public const string Mgo = "Mgo";
        public const string HeavyFuel = "HeavyFuel";
        public const string Lng = "Lng";
        public const string Battery = "Battery";
        public const string MgoBattery = "Mgo-battery";
        public const string MgoBatteryLng = "Mgo-battery-lng";

        public new static Dictionary<string, string> ValuesAndDescriptions
        {
            get
            {
                return new Dictionary<string, string> {
                    {Mgo, "MGO"},
                    {HeavyFuel, "Heavy Fuel"},
                    {Lng, "LNG"},
                    { Battery, "Battery" },
                    { MgoBattery, "MGO & Battery" },
                    { MgoBatteryLng, "MGO, LNG & Battery" }
                };
            }
        }

        public string GetDescription(string value)
        {

            return !string.IsNullOrEmpty(value) && ValuesAndDescriptions.ContainsKey(value) ? ValuesAndDescriptions[value] : null;
        }

        public string GetValue(string description)
        {
            return ValuesAndDescriptions.Where(v => v.Value == description).Select(v => v.Key).FirstOrDefault();
        }
    } 

Each of these constant classes has a dictionary field, ValuesAndDescriptions as well as two common methods, GetDescription & GetValue.

The issue i have is that when I stick these variables in a common base class like this:

    public class ConstantBase
    {
        public static string GetDescription(string value)
        {

            return !string.IsNullOrEmpty(value) && ValuesAndDescriptions.ContainsKey(value) ? ValuesAndDescriptions[value] : null;
        }

        public static string GetValue(string description)
        {
            return ValuesAndDescriptions.Where(v => v.Value == description).Select(v => v.Key).FirstOrDefault();
        }

        public static Dictionary<string, string> ValuesAndDescriptions = new Dictionary<string, string>();
    }

ValuesAndDescriptions in the base class is never populated, and I cant override it from the child class because it is a static property, and hence the methods GetValue() and GetDescription are always returning null.

I dont want to just replicate GetValue(0 & GetDescription() in each constant class, but im not sure on the best approach.

FYI, the constant classes need to be static as I need to be able to call each of the constant classes like this:

FuleTypeConstant.GetValue(XXXX)

without actually instantiating anything.

You don't need to manually populate the ValuesAndDescriptions . You can use reflection for that:

public static class FuelTypeConstant
{
    public const string Mgo = "Mgo";
    public const string HeavyFuel = "HeavyFuel";
    public const string Lng = "Lng";
    public const string Battery = "Battery";
    public const string MgoBattery = "Mgo-battery";
    public const string MgoBatteryLng = "Mgo-battery-lng";
    public static readonly string Extra = "Extra"; //Won't be included during reflection

    private static readonly Dictionary<string, string> ValuesAndDescriptions;

    static FuelTypeConstant()
    {
        ValuesAndDescriptions = typeof(FuelTypeConstant)
            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
            .Where(fi => fi.IsLiteral && !fi.IsInitOnly)
            .ToDictionary(fi => fi.Name, fi => fi.GetRawConstantValue().ToString());
    }
    ...       
}
  • I've marked your ValuesAndDescriptions to private since it is an implementation detail
    • Because you have two methods to extract value or description that's why there is no need to expose them
  • I've also marked it as readonly because it is populated inside the the static constructor
  • The reflection code fetches only the const fields so others will be excluded (like public static readonly string Extra = "Extra"; )
  • Finally with the ToDictionary I've mapped the FieldInfo objects to the desired format

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM