Reputation: 599
In Java, we can declare enums
like so
public enum ChangeFlag
{
NEW("New"),
DELETED("Deleted"),
REVISED("Revised");
private final String text;
ChangeFlag(String text)
{
this.text = text;
}
public String toString()
{
return text;
}
}
Is there any elegant equivalent to this for C#?
Edit:
public static class FooExtensions
{
public static string GetDescription(this Foo @this)
{
switch (@this)
{
case Foo.Bar:
return "A bar";
}
}
}
Could you explain what the parameters in GetDescription(this Foo @this) mean?
I'm not used to seeing what this Foo @this
refers to
Upvotes: 0
Views: 3012
Reputation: 1965
A compact and fault-proof implementation variant, of the enum description getter extension method:
/// <exception cref="AmbiguousMatchException">More attributes found. </exception>
/// <exception cref="TypeLoadException">Cannot load custom attribute.</exception>
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string enumName = Enum.GetName(type, value);
if (enumName == null)
{
return null; // or return string.Empty;
}
FieldInfo typeField = type.GetField(enumName);
if (typeField == null)
{
return null; // or return string.Empty;
}
var attribute = Attribute.GetCustomAttribute(typeField, typeof(DescriptionAttribute));
return (attribute as DescriptionAttribute)?.Description; // ?? string.Empty maybe added
}
Also a comparison extension method (which uses the upper) for the description may be useful:
public static bool DescriptionEquals(this Enum value, string inputForComparison,
StringComparison comparisonType = StringComparison.InvariantCultureIgnoreCase)
{
string description;
try
{
description = value.GetDescription();
}
catch (Exception ex) when (ex is AmbiguousMatchException || ex is TypeLoadException)
{
return false;
}
if (description == null || inputForComparison == null)
{
return false;
}
return inputForComparison.Equals(description, comparisonType);
// || inputForComparison.Equals(value.ToString(), comparisonType); may be added
}
Upvotes: 2
Reputation: 4314
internal static class Program
{
private static void Main(string[] args)
{
ChangeFlag changeFlag = ChangeFlag.REVISED;
Console.WriteLine(changeFlag.GetDescription());
Console.Read();
}
public enum ChangeFlag
{
[Description("New")]
NEW,
[Description("Deleted")]
DELETED,
[Description("Revised")]
REVISED
}
}
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
if (fi != null)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
}
return value.ToString();
}
}
Upvotes: 2
Reputation: 178820
You can use DescriptionAttribute
:
public enum Foo
{
[Description("A bar")]
Bar
}
Which you would then extract via TypeDescriptor.GetAttributes
or Type.GetCustomAttributes
.
Or you could use extension methods:
public enum Foo
{
Bar
}
public static class FooExtensions
{
public static string GetDescription(this Foo @this)
{
switch (@this)
{
case Foo.Bar:
return "A bar";
}
}
}
// consuming code
var foo = Foo.Bar;
var description = foo.GetDescription();
The latter approach also gives you more control when it comes to localization, since you could always look up the description in a resource file, for example.
Upvotes: 5