ToString() question

  • Thread starter Thread starter William Stacey
  • Start date Start date
W

William Stacey

Just create a private or static method in a class that returns the right
thing. This is almost as good as having a ToString and probably no slower:

private void button4_Click(object sender, System.EventArgs e)
{
ShippingMethods sm = ShippingMethods.smSnailMail;
Console.WriteLine("Ship Method:" + ShipMethods(sm));
}

private string ShipMethods(ShippingMethods sm)
{
switch(sm)
{
case ShippingMethods.smEmail:
return "Email";
case ShippingMethods.smSnailMail:
return "US Mail";
default:
return "Unknown";
}
}
 
Say I have an enum

private enum ShippingMethods
{
smSnailMail,
smEmail
}

If create var of type ShippingMethods when I call ToString() on it, I
get the actual enumeration. I would like to make ToString() return a
more human readable format.

EG:
ShippingMethods eShip = ShippingMethods.smSnailMail
Console.WriteLine(eShip.ToString());

outputs
smSnailMail

I would prefer

ShippingMethods eShip = ShippingMethods.smSnailMail
Console.WriteLine(eShip.ToString());

outputs
US Mail

I tried adding a ToString method in the enum definition, which does
not compile. So my question is how I can override ToString() to do
this?

Thanks
Matt
 
raffelm,

You can not do this, as enumerations are sealed by default. However,
you can add a Description attribute to each member of the enumeration, and
then use reflection to access it. When enumerations are created, they are
treated as classes with constants attached to them with the values of the
individual elements in the enumeration. So, you can access them using
reflection, using the names of the values in the enumeration as the field
names. You can do this:

// Notice the description attribute here. It is in the
System.ComponentModel namespace.
enum ShippingMethods
{
[Description("US Mail")]
smSnailMail,

[Description("E-mail")]
smEmail
}


/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
// Get a value in the enumeration.
ShippingMethods pintMethod = ShippingMethods.smEmail;

// Get the type for the enumeration.
Type pobjEnumType = typeof(ShippingMethods);

// Now get the static field that represents the
// value.
FieldInfo pobjInfo =
pobjEnumType.GetField(Enum.GetName(typeof(ShippingMethods), pintMethod));

// Now get the attribute.
DescriptionAttribute pobjDescription = (DescriptionAttribute)
pobjInfo.GetCustomAttributes(typeof(DescriptionAttribute), true)[0];

// Write the description.
Console.WriteLine(pobjDescription.Description);

// That's all folks.
return;
}
}

Hope this helps.
 
Thnx. I like this implementation. I created a generic function that
can return the description for any type that has description attribute
applied

public static string GetEnumeratorDescription(Type enumType, int
nIndex)
{
string strRet = "<na>";

try
{
// Now get the static field that represents the value.
FieldInfo objInfo =
enumType.GetField(Enum.GetName(enumType, nIndex));

// Now get the attribute.
DescriptionAttribute objDescription =
(DescriptionAttribute)
objInfo.GetCustomAttributes(typeof(DescriptionAttribute), true)[0];

// get the description.
strRet = objDescription.Description;

}
catch(Exception)
{
Console.WriteLine("Developer error: an enumerator of " +
enumType + " does not have the expected descriptions.");
}

return strRet;
}

Matt

Nicholas Paldino said:
raffelm,

You can not do this, as enumerations are sealed by default. However,
you can add a Description attribute to each member of the enumeration, and
then use reflection to access it. When enumerations are created, they are
treated as classes with constants attached to them with the values of the
individual elements in the enumeration. So, you can access them using
reflection, using the names of the values in the enumeration as the field
names. You can do this:

// Notice the description attribute here. It is in the
System.ComponentModel namespace.
enum ShippingMethods
{
[Description("US Mail")]
smSnailMail,

[Description("E-mail")]
smEmail
}


/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
// Get a value in the enumeration.
ShippingMethods pintMethod = ShippingMethods.smEmail;

// Get the type for the enumeration.
Type pobjEnumType = typeof(ShippingMethods);

// Now get the static field that represents the
// value.
FieldInfo pobjInfo =
pobjEnumType.GetField(Enum.GetName(typeof(ShippingMethods), pintMethod));

// Now get the attribute.
DescriptionAttribute pobjDescription = (DescriptionAttribute)
pobjInfo.GetCustomAttributes(typeof(DescriptionAttribute), true)[0];

// Write the description.
Console.WriteLine(pobjDescription.Description);

// That's all folks.
return;
}
}

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

raffelm said:
Say I have an enum

private enum ShippingMethods
{
smSnailMail,
smEmail
}

If create var of type ShippingMethods when I call ToString() on it, I
get the actual enumeration. I would like to make ToString() return a
more human readable format.

EG:
ShippingMethods eShip = ShippingMethods.smSnailMail
Console.WriteLine(eShip.ToString());

outputs
smSnailMail

I would prefer

ShippingMethods eShip = ShippingMethods.smSnailMail
Console.WriteLine(eShip.ToString());

outputs
US Mail

I tried adding a ToString method in the enum definition, which does
not compile. So my question is how I can override ToString() to do
this?

Thanks
Matt
 
Back
Top