Sunday, October 22, 2006

String descritions from enums in C#

Anyone just looking for code can skip to the end.

My AE Item Maker has a SingleUseItem class, which uses an enum for each different kind of single use item.

public enum SUType
{
INVALID,
POTION,
OIL,
DETONATION,
OTHER,
}
Among other things I use the enum to generate names for items. In C++, I would probably write a function to convert the enum to the string I wanted, but this isn't c++, and I wanted to try something different.

My first thought was to use the nift ToString() method. This got me literal strings for values, like "INVALID", "POTION", etc. It was close, but not really what I wanted. So I turned to my favorite search engine for help.

The results were mixed. It seems you can't actually override the ToString() method on an enum. But I did find the next best thing.

First, I add a Description attribute to the enum (you need System.ComponentModel for this)

public enum SUType
{
[Description("Unknown type")]
INVALID,
[Description("Potion")]
POTION,
[Description("Oil")]
OIL,
[Description("Detonation")]
DETONATION,
[Description("Single Use Item")]
OTHER,
}


Next I added this public static method in a helper class:


 

public class ItemHelper
{
/// <summary>
/// Returns the DescriptionAttirbute for an
/// enum.
/// </summary>
/// <param name="nType">Any enum</param>
/// <returns>DescriptionAttribute for that
/// enum, if it exists</returns>
public static string GetTypeDescription(Enum nType)
{
Type oSystype = nType.GetType();
string strName = System.Enum.GetName(oSystype, nType);
FieldInfo oFieldInfo = oSystype.GetField(strName);
object[] rgObjs =
oFieldInfo.GetCustomAttributes(
typeof(DescriptionAttribute), false);
foreach (object obj in rgObjs)
{
DescriptionAttribute oDesc = obj as
DescriptionAttribute;
if (oDesc != null)
{
return oDesc.Description;
}
}

return "Unknown";
}
}

 


You use it like this:

string strType = ItemHelper.GetTypeDescription(m_nType);

This isn't perfect.  For one, if you have multiple description attributes you aren't guaranteed to find a particular one first.  It also doesn't handle localization at all.  But this works for what I need right now.

No comments: