98

I have the following enum:

public enum Urgency {
    VeryHigh = 1,
    High     = 2,
    Routine  = 4
}

I can fetch an enum "value" as string like this:

((int)Urgency.Routine).ToString() // returns "4"  

Note: This is different from:

Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine       // returns 4

Is there a way I can create an extension class, or a static utliity class, that would provide some syntactical sugar? :)

4
  • 4
    Can you be more precise about what you are looking for? Commented Aug 9, 2010 at 22:35
  • i.e. enumValue.ToValueString() == the int value? Commented Aug 9, 2010 at 22:36
  • The underlying int value - but as a string (not the enum as a string) Rather than remember the archane syntax of casting to an int and then to a string, a static class with a method that takes any Enum value would make it easier to use. I suspect the language may not support what I'm after. Commented Aug 9, 2010 at 22:42
  • .. think I did what you want. Commented Aug 9, 2010 at 23:07

8 Answers 8

172

You should just be able to use the overloads of Enums ToString method to give it a format string, this will print out the value of the enum as a string.

public static class Program
{
    static void Main(string[] args)
    {
        var val = Urgency.High;
        Console.WriteLine(val.ToString("D")); 
    }
}

public enum Urgency 
{ 
    VeryHigh = 1,
    High = 2,
    Low = 4
}
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, nice bit of lateral thinking in providing the same result with a different approach to the query. The code public static string NumberString(this Enum enVal){return enVal.ToString("D");} should be what takes your idea and turns it into the extension method asked for.
I love this one either than the other that use extension method. By creating extension method you just add unnecessary dependency to your code. Remember the least dependency you have the better your code!!
To apply on multiple enum values (example): new[] { ProductStatus.Open, ProductStatus.Deprecated }.Select(s => s.ToString("D"))
or directly Urgency.High.ToString("D")
31

In order to achieve more "human readable" descriptions for enums (e.g. "Very High" rather than "VeryHigh" in your example) I have decorated enum values with attribute as follows:

public enum MeasurementType
{
    Each,

    [DisplayText("Lineal Metres")]
    LinealMetre,

    [DisplayText("Square Metres")]
    SquareMetre,

    [DisplayText("Cubic Metres")]
    CubicMetre,

    [DisplayText("Per 1000")]
    Per1000,

    Other
}


public class DisplayText : Attribute
{

    public DisplayText(string Text)
    {
        this.text = Text;
    }


    private string text;


    public string Text
    {
        get { return text; }
        set { text = value; }
    }
}

Then, used an extension method like this:

    public static string ToDescription(this Enum en)
    {

        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(
                                          typeof(DisplayText),

                                          false);

            if (attrs != null && attrs.Length > 0)

                return ((DisplayText)attrs[0]).Text;

        }

        return en.ToString();

    }

You can then just call

myEnum.ToDescription()
in order to display your enum as more readable text.

5 Comments

I've done similar, though often just depend on the convention of camel-casing. Doesn't do what the question asks though.
Thanks - but doesn't return the int value - as a string :)
You didn't add the declaration of the DisplayText attribute. Could you possibly add it?
Thanks Stuart. It's working now. Unfortunately I can't give you multiple +1s so I guess the one I have earlier should suffice.
I thought this might have been an ex colleague who did this as I've used the same solution multiple times, even down to calling the attribute DisplayText - though I also have played with further decorating enums so I go the long way through a "GetAttrib<TEnum, TAttrib>()" function - return (TAttrib)enumValue.GetType().GetMember(enumValue.ToString()).First().GetCustomAttributes(typeof(TAttrib), false).FirstOrDefault();
6

If you want to just deal with this enum, use Mark Byer's solution.

For a more general solution:

public static string NumberString(this Enum enVal) 
{
    return Convert.ToDecimal(enVal).ToString("0");
}

Converting to decimal means you don't need to deal with the 8 different allowed underlying integral types explicitly, as all of them convert losslessly to decimal but not to each other (ulong and long don't convert losslessly between each other but both can handle all the rest). Doing that would probably be faster (esp. if you pick well in your order of comparison), but a lot more verbose for relatively little gain.

Edit:

The above isn't as good as Frankentosh's though, Frankentosh saw through the question to the real problem and solves it very eloquently.

Comments

5

a simple approach

((Urgency)4).ToString() // returns "Routine"

1 Comment

ts asks about numeric value of enum presented as string
4

Great stuff ... I have now added an extension method to my project

public static class EnumExtensions 
{ 
    public static string NumberString(this Enum enVal) 
    { 
        return enVal.ToString("D"); 
    }
} 

Now I can get the int value - as a string - by calling Urgency.Routine.NumberString(); Thanks to Frankentosh and Jon :)

Comments

3

You can write an extension method for your specific type:

public static class UrgencyExtension
{
    public static string ToIntegerString(this Urgency u)
    {
        return ((int)u).ToString();
    }
}

Use as follows:

Urgency u = Urgency.Routine;
string s = u.ToIntegerString();

Comments

3

How about a little reflection? Should work with all underlying types.

public static class EnumTools
{
    public static string ToRawValueString(this Enum e)
    {
        return e
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .First(f => f.Name==e.ToString())
            .GetRawConstantValue()
            .ToString();
    }
}

Then:

Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"

3 Comments

First() is going to fail if there isn't an defined value in the enumeration matching the value, particularly common with flag enums and possible in other cases (whenever Enum.IsDefined(e.GetType(), e) returns false) This needs to be more defensive for such a case, and then the fall-back to not fail on a valid (if awkward) value would be to use the non-reflection approach, when when you refactored would mean you'd then delete the reflection bit unless it was provably much faster.
@Jon : I don't see how an Enum's type could possibly not contain an entry for it. What am I missing? EDIT: Gotcha, the Enum could be ORed flags. I concur with your comment.
That's the most common case. It's also valid to cast any value of the underlying type to an enum type, hence Enum.IsDefined() existing to allow one to catch cases where that would be an invalid argument to a method or an invalid value for a property.
3

If you wanted, you could make the extension method work for all enums:

public static string ToValueString(this Enum enumValue) 
{
    if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
        return ((int)(object)enumValue).ToString();
    else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
        return ((byte)(object)enumValue).ToString();
    ... 
}        

2 Comments

+1: Interesting... but at the same time slightly unusual to see that double cast. Nice trick. :) Could use Enum instead of T where T : struct?
You're right. Not sure why I thought that was helpful in that case. Changed it to reflect your suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.