Wusiji
Wusiji

Reputation: 599

Alternative Names for C# enum

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

Answers (3)

Teodor Tite
Teodor Tite

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

Jaex
Jaex

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

Kent Boogaart
Kent Boogaart

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

Related Questions