tags:

views:

2096

answers:

8
+11  Q: 

Enum ToString

My enum consists of the following values:

private enum PublishStatusses{
 NotCompleted,
 Completed,
 Error
};

I want to be able to output these values in a user friendly way though.
In this SO post, there is a lot of code that I can't seem to compile..
I don't need to be able to go from string to value again.
Why is it not compiling at my machine? How can I get such a result?

+20  A: 

I use the Description attribute from the System.ComponentModel namespace. Simply decorate the enum and then use this code to retrieve it:

public static string GetDescription<T>(this object enumerationValue)
            where T : struct
        {
            Type type = enumerationValue.GetType();
            if (!type.IsEnum)
            {
                throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
            }

            //Tries to find a DescriptionAttribute for a potential friendly name
            //for the enum
            MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
            if (memberInfo != null && memberInfo.Length > 0)
            {
                object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0)
                {
                    //Pull out the description value
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            //If we have no description attribute, just return the ToString of the enum
            return enumerationValue.ToString();

        }
Ray Booysen
Nice, I will put that in my helper lib :) Thx
borisCallens
Extension methods are quicker to code, use, and support than metadata-based methods.
Will
+1  A: 

If you want something completely customizable, try out my solution here:

http://www.kevinwilliampang.com/post/Mapping-Enums-To-Strings-and-Strings-to-Enums-in-NET.aspx

Basically, the post outlines how to attach Description attributes to each of your enums and provides a generic way to map from enum to description.

Kevin Pang
A: 
foreach( PublishStatusses p in Enum.GetValues (typeof(PublishStatusses)) )
{
   Console.WriteLine (p);
}
Frederik Gheysels
How does that answer my question exactly?
borisCallens
It allows you to get all your enum values, and output them. That's what you wanted ?
Frederik Gheysels
"I want to be able to output these values in a user friendly way"
borisCallens
+6  A: 

That other post is Java. You can't put methods in Enums in C#.

just do something like this:

PublishStatusses status = ...
String s = status.ToString();

If you want to use different display values for your enum values, you could use Attributes and Reflection.

Lemmy
HA! Silly me. I'm becoming to C#centric lately :P
borisCallens
toString is not safe in all cases - an enum with multiple entries with the same value (say for integer enums) will return the key of the first matching value, not the key of the item tested, this is why Enum.GetName is preferred
annakata
Well it was the easiest solution for his specific enum
Lemmy
+7  A: 

The easiest solution here is to use a custom extension method (in .NET 3.5 at least - you can just convert it into a static helper method for earlier framework versions).

public static string ToCustomString(this PublishStatusses value)
{
    switch(value)
    {
        // Return string depending on value.
    }
    return null;
}

I am assuming here that you want to return something other than the actual name of the enum value (which you can get by simply calling ToString).

Noldorin
Although valid, I like the attribute way more. That way I can put my toSTring method in a seperate library, whilst putting the custom string representation with the enum itself
borisCallens
Hey that's a neat trick
Lemmy
Fair enough. I suppose one advantage of this method is that you can include an argument with the method specifying some state variable, and then change what string representation is returned depending on this.
Noldorin
Yes, it all depends on the scope of the method I guess. While the Attribute way is more generic, your solution is more localized.. It's all about needs in the end.
borisCallens
You can put extension methods anywhere you want. You just have to reference it where you want to use them.
Will
Yes, but this would mean that this one extention method should be rewritten every time you introduce a new enum you want to have a friendly name for. This would also mean that ALL your applications would carry around friendly names for ALL your other applications...
borisCallens
+1  A: 

Maybe I'm missing something, but what's wrong with Enum.GetName?

public string GetName(PublishStatusses value)
{
  return Enum.GetName(typeof(PublishStatusses), value)
}

edit: for user-friendly strings, you need to go through a .resource to get internationalisation/localisation done, and it would arguably be better to use a fixed key based on the enum key than a decorator attribute on the same.

annakata
I returns the literal value of the enum, not some user friendly one.
borisCallens
oic - well there's a pretty big case that you have to go through a string resource library based on this value then, because the alternative (decorator attribs) won't support I18N
annakata
In case of I18N I would make the GetDescription() method search in the resource lib for a translated string and fall back to the description and then fall back to the literal.
borisCallens
+11  A: 

I do this with extension methods:

public enum ErrorLevel
{
  None,
  Low,
  High,
  SoylentGreen
}

public static class ErrorLevelExtensions
{
  public static string ToFriendlyString(this ErrorLevel me)
  {
    switch(me)
    {
      case ErrorLevel.None:
        return "Everything is OK";
      case ErrorLevel.Low:
        return "SNAFU, if you know what I mean.";
      case ErrorLevel.High:
        return "Reaching TARFU levels";
      case ErrorLevel.SoylentGreen:
        return "ITS PEOPLE!!!!";
    }
  }
}
Will
dangit, noldorim snuck in on me. Giving him an upvote.
Will
yes, thanks for the input though. I put some remarks in noldorim's post regarding this solution.
borisCallens
Why, thank you Will.
Noldorin
This is quite nice, actually. Very helpful.
Andrew Backer
I love this so much I want to marry it.
JustLooking
+2  A: 

With respect to Ray Booysen, there is a bug in the code: http://stackoverflow.com/questions/479410/enum-tostring/479417#479417

You need to account for multiple attributes on the enum values.

public static string GetDescription<T>(this object enumerationValue)
            where T : struct
    {
        Type type = enumerationValue.GetType();
        if (!type.IsEnum)
        {
            throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
        }

        //Tries to find a DescriptionAttribute for a potential friendly name
        //for the enum
        MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
        if (memberInfo != null && memberInfo.Length > 0)
        {
            object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attrs != null && attrs.Length > 0 && attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault() != null)
            {
                //Pull out the description value
                return ((DescriptionAttribute)attrs.Where(t=>t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()).Description;
            }
        }
        //If we have no description attribute, just return the ToString of the enum
        return enumerationValue.ToString();
Joel MC