0

I really don't know a better way to phrase the title...

I have several enums in my project and what I'm trying to do is output a string representing the selected enum value.

Consider the following enum:

public enum MedicineType
{
    Drops,
    Liquid,
    Cream,
    Powder
}

If the user selected the Liquid value, I want to output the string "02":

public string GetStringFromEnum(MedicineType medicineType)
{
    // Output values should be something like:
    // Drops = "01",
    // Liquid = "02",
    // Cream = "03",
    // Powder = "04"
    return ("0" + (int)medicineType + 1)
}

If the selected index is < 10, it should pad with a 0 but if its 10 or more, it should just output the value:

var selectedValue = (int)medicineType + 1;
return (selectedValue > 10) ? "0" + selectedValue : selectedValue.ToString();

Where I'm falling down is that the code to get the string representation for the selected enum value is going to be pretty much identical for every enum (I have 26) so I don't want to be repeating this code in a new method for all 26 enums. I'd prefer to have a call to a sincle GetStringFromEnum method that will accept any enum as a parameter.

Is this possible? If not, what would be a decent workaround that would limit code repetition?

Ortund
  • 8,095
  • 18
  • 71
  • 139
  • 1
    Possible duplicate of https://stackoverflow.com/questions/12916061/how-can-i-convert-the-integer-output-of-an-enum-to-a-two-character-string – joakimriedel Dec 01 '17 at 08:35
  • Possible duplicate of [How can I convert the integer output of an enum to a two character string?](https://stackoverflow.com/questions/12916061/how-can-i-convert-the-integer-output-of-an-enum-to-a-two-character-string) – Peter B Dec 01 '17 at 08:45

2 Answers2

0

No, there is no nice way to restrict generic type to enum the best you can do is make it struct where T: struct.

string GetStringFromEnum<T>(T value) : where T :struct
{ 
    if(!typeof(T).IsEnum) 
        throw new ArgumentException("value must be enum", nameof(value));
    return ((int)value + 1).ToString("D2"); 
}
Rafal
  • 12,391
  • 32
  • 54
0

First improvement could be to avoid +1 on enum values:

public enum MedicineType
{
    Drops = 1,
    Liquid = 2,
    Cream = 3,
    Powder = 4,
    Dust = 10
}

One strategy could be a extension method to avoid repeating code and improve it with .net string formating:

public static class GetStringFromEnum
{
  public static string ToFriendlyString(this MedicineType me)
  {
    return  ((int)me).ToString("D2");
  }
  public static string ToFriendlyString(this OtherEnum oe)
  {
    return  ((int)oe).ToString("D2");
  }
}

See @Rafal answer for generic version. (I don't like it)

Another strategy could be using an Attribute and reflection. (I don't like it):

public enum MedicineType
    {
        [Description("01")]
        Drops,
        [Description("02")]
        Liquid,
        [Description("03")]
        Cream,
        [Description("04")]
        Powder,
        [Description("10")]
        Dust
    }

See Enum ToString with user friendly strings for specific and generic implementations about retrieving the attribute.

My last words: I think you are falling into primitive obsession antipattern.

jlvaquero
  • 8,571
  • 1
  • 29
  • 45
  • Tnx for report the typo. ((int)me.GetTypeCode()) return the 9th element of TypeCode Enum wich is Int32 for enums by default. Check this fiddle: https://dotnetfiddle.net/veZqaL – jlvaquero Dec 01 '17 at 09:55