45

Basically a series of titles will be passed into the switch statement and I need to compare them against the string values of the enum. But I have little to no idea how to do this correctly.

Also, I don't know if this is even the best approach so if anyone has any ideas?

For example:

enum
{
    doctor = "doctor",
    mr = "mr",
    mrs = "mrs"
}

and then switch through the string values I've assigned them.

11 Answers 11

67

I found that the best way for me to do this is by using the System.ComponentModel.DescriptionAttribute attribute on the enum values.

Here is an example:

using System.ComponentModel;

public enum ActionCode
{
    [Description("E")]
    Edit,
    [Description("D")]
    Delete,
    [Description("R")]
    Restore
}

Then, to use it, create an extension method on a static class like so:

Edit: I rewrote the method to include a great suggestion from Laurie Dickinson so that the method returns the name of the enum value when there is no Description attribute. I also refactored the method to try to improve functionality. It now works for all Enums without using IConvertible.

public static class Extensions
{
    public static string GetDescription(this Enum e)
    {
        var attribute =
            e.GetType()
                .GetTypeInfo()
                .GetMember(e.ToString())
                .FirstOrDefault(member => member.MemberType == MemberTypes.Field)
                .GetCustomAttributes(typeof(DescriptionAttribute), false)
                .SingleOrDefault()
                as DescriptionAttribute;

        return attribute?.Description ?? e.ToString();
    }
}

So, to get the string associated with our enum above, we could use the following code:

using Your.Extension.Method.Namespace;

...

var action = ActionCode.Edit;
var actionDescription = action.GetDescription();

// Value of actionDescription will be "E".

Here is another sample Enum:

public enum TestEnum
{
    [Description("This is test 1")]
    Test1,
    Test2,
    [Description("This is test 3")]
    Test3

}

Here is the code to see the description:

var test = TestEnum.Test2;
var testDescription = test.GetDescription();
test = TestEnum.Test3;
var testDescription2 = test.GetDescription();

Results will be:

testDescription: "Test2"
testDescription2: "This is test 3"

I wanted to go ahead and post the generic method as it is much more useful. It prevents you from having to write a custom extension for all of your enums.

Sign up to request clarification or add additional context in comments.

8 Comments

Works but is incredibly slow
@ceds - Agreed, but the cost may be worth it. It is in our case in the very few places we use this feature. It's especially slow if the backing store is a database. But the benefits and use cases exist.
Thanks, this was helpful. I updated it to return the name of the enum if there was no Description, returning type.GetEnumName(val) if descriptionAttribute is null.
@Laurie Dickinson - That's a great idea. Thanks for sharing.
@David Storfer That's probably not a bad idea, though I should change it to First() and eliminate the default. I believe that we're pretty much guaranteed to have a value at that point since it's an enum. It shouldn't be null.
|
17

You can't have an enum with an underlying type of string. The underlying type can be any integral type except char.

If you want to translate a string to your enum then you'll probably need to use the Parse or TryParse methods.

string incoming = "doctor";

// throws an exception if the string can't be parsed as a TestEnum
TestEnum foo = (TestEnum)Enum.Parse(typeof(TestEnum), incoming, true);

// try to parse the string as a TestEnum without throwing an exception
TestEnum bar;
if (Enum.TryParse(incoming, true, out bar))
{
    // success
}
else
{
    // the string isn't an element of TestEnum
}

// ...

enum TestEnum
{
    Doctor, Mr, Mrs
}

1 Comment

It is solution for description but question was quiet diffrent "How to assign string values to enums and use that value in a switch" but theres no assign at all.
5

Enum can only have integral underlying types (except char). Therefore you cannot do what you want, at least directly.

However you can translate the string you have to the enum type:

EnumType eVal = (EnumType)Enum.Parse(typeof(EnumType), strValue);

switch(eVal)
{
    case EnumType.doctor:/*...*/; break;
    case EnumType.mr: /*...*/; break;
}

Comments

5

I believe the standard way to do this is to use a static class with readonly string properties that return the value you want.

Comments

5

I wanted to add another answer for anyone using C# 6 or greater.

If you are only wanting to get the name of the Enum value, you could use the new nameof() method introduced in C# 6.

string enumName = nameof(MyEnum.EnumVal1); // enumName will equal "EnumVal1"

While this may seem like overkill at first glance (why not just set the value of the string to "EnumVal1" to start with?), it will give you compile-time checking to make sure the value is valid. So, if you ever change the name of the enum value and forget to tell your IDE to find and replace all references, it will not compile until you fix them.

Comments

4

This is not the kind of thing that should be hard-coded. It should be data-driven, possibly read from an external file or database. You could store them in a Dictionary and use the keys to drive your logic.

4 Comments

Hard-coding enum descriptions is no more incorrect than naming classes after real-world domain objects. Sometimes a Fish.BabelFish will always be a "Babel fish". A case could be made for getting the values from a localized resource (for globalization), but you don't have to get every piece of information from a database or external file.
@Michael Earls - Applications come and go, but the data lives forever. If you put it in the database, it can be used from any number of applications. asktom.oracle.com/pls/asktom/…
@dcp - Good point. Thanks for the link. It was very informative.
It's hard to make that kind of assessment based on the sample text in the OP. Maybe it was just a simple example he threw together to make his point clear, but in practice he'd be using something that was more appropriate for this solution. I'm using it for cookie types/names. A dictionary is not strongly typed so to me that's a bad idea.
3

Enumerations cannot be of string type.

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

2 Comments

I didn't say I wanted it to be of type string. I said I wanted to assign a string value to it. I've seen it done before and wanted to know how to implement it.
My apologies then, I read it as the same thing since the underlying values are the type of the enum.
1

Why not to use just pure enum and switches?

enum Prefix
{
    doctor,
    mr,
    mrs
}

Then you can use is like

string case = "doctor";

switch ((Prefix)Enum.Parse(typeof(Prefix), "doctor"))
{
    case Prefix.doctor:
        ...
        break;
    ...
    default:
        break;
}

2 Comments

enums have to be one word, so Lance Corporal for example, would cause me problems
you can create a map Dictionary<string, Prefix> map, fill it, then given a string "Lance Corporal" find an appropriate enum value (like Prefix p = map["Lance Corporal"];) and do a switch on the enum type.
1

If you're really hardcore and on c# 8...

public static string GetDescription(this VendorContactType enumval) =>
        enumval switch {
            VendorContactType.AccountContact => "Account Contact",
            VendorContactType.OrderContact => "Order Contact",
            VendorContactType.OrderContactCC => "Order Contact CC",
            VendorContactType.QualityContact => "Quality Contact",
            VendorContactType.ShippingContact => "Shipping Contact",
            _ => ""
        };

I realize this won't accept all of your program's enums but it's what I use and I like it.

Comments

0

Have a read of this tutorial to understand how enums work. There are examples of switch statements too.

1 Comment

I skimmed through but didn't see anything about assigning string values there.
0

Just sharing my solution. By downloading the nuget package Extension.MV, a method is available for getting the string from a Enum Description

public enum Prefix
{
    [Description("doctor")]
    doctor = 1,
    [Description("mr")]
    mr = 2,
    [Description("mrs")]
    mrs = 3
}

public static class PrefixAdapter {

    public static string ToText(this Prefix prefix) {
        return prefix.GetEnumDescription();
    }

    public static Prefix ToPrefix(this string text) {
        switch (text)
        {
            case "doctor"
                return Prefix.doctor;
            case "mr"
                return Prefix.mr;
            case "ms"
                return Prefix.mrs;
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.