Enum With String Values In C# (2023)

.NET .NET 3.5 ASP.NET Attributes C# MICROSOFT

Hello again,

I am currently making a Virtual Earth asp.net ajax server control and came to the point where I had to replicate the enums in my classes, but the issue with them is that the enums do not use integer values but string ones. In C# you cannot have an enum that has string values :(. So the solution I came up with (I am sure it has been done before) was just to make a new custom attribute called StringValueAttribute and use this to give values in my enum a string based value.

Note: All code here was written using .NET 3.5 and I am using 3.5 specific features like automatic properties and exension methods, this could be rewritten to suit 2.0 quite easily.

First I created the new custom attribute class, the source is below:

/// <summary>
/// This attribute is used to represent a string value
/// for a value in an enum.
/// </summary>
public class StringValueAttribute : Attribute {

#region Properties

/// <summary>
/// Holds the stringvalue for a value in an enum.
/// </summary>
public string StringValue { get; protected set; }

#endregion

#region Constructor

/// <summary>
/// Constructor used to init a StringValue Attribute
/// </summary>
/// <param name="value"></param>
public StringValueAttribute(string value) {
this.StringValue = value;
}

#endregion

}


Then I created a new Extension Method which I will use to get the string value for an enums value:

/// <summary>
/// Will get the string value for a given enums value, this will
/// only work if you assign the StringValue attribute to
/// the items in your enum.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string GetStringValue(this Enum value) {
// Get the type
Type type = value.GetType();

// Get fieldinfo for this type
FieldInfo fieldInfo = type.GetField(value.ToString());

// Get the stringvalue attributes
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
typeof(StringValueAttribute), false) as StringValueAttribute[];

// Return the first if there was a match.
return attribs.Length > 0 ? attribs[0].StringValue : null;
}

So now create your enum and add the StringValue attributes to your values:

public enum Test : int {
[StringValue("a")]
Foo = 1,
[StringValue("b")]
Something = 2
}

Now you are ready to go, to get the string value for a value in the enum you can do so like this now:

Test t = Test.Foo;
string val = t.GetStringValue();

- or even -

string val = Test.Foo.GetStringValue();

All this is very easy to implement and I like the ease of use you get from the extension method [I really like them :)] and it gave me the power I needed to do what I needed. I haven't tested the performance hit that the reflection may give and might do so sometime soon.

Thanks
Stefan

  • You can use this attribute for your StringValueAttribute:
    [AttributeUsage(AttributeTargets.Field)]

    If you have that, you can only use the attribute on the fields in an enum. :-)

  • Thanks for that mate, could be handy to stop people using it for purposes it is not made to do :P and I am sure it will happen.

    Thanks
    Stefan

  • Hi Stefan,

    Interesting approach to this. I also faced the same problem a while ago and posted my solution called SpecializedEnum to CodePlex recently. It provides fairly thorough emulation of enum's behaviors with any arbitrary object type.

    James.

  • I like this idea. I do have one question though. How do you do the reverse? Using your example, if you load the field from a database, and the field contains "b", how do you set the object property (which is of type Test) to the proper enum value? In other words, how would you implement the extension method SetValueByString? I ask because I've tried to do this and have failed so far :(

  • How do you set the string value? Ie you read the value "b" from the database and want to set the enum to that value.

  • Unfortunately you can't use this where a constant value is expected, such as switch statements. So it kind of breaks the contract an Enum would normally have with its consumers.

  • Tarek,

    I did not take this from anywhere? I just looked at that article and it is honestly the first time I have seen this.

    I can see why you think I took this it is the same solution to the problem. But it is possible that 2 people out of 6,602,224,175 in the world could came up with the same idea, and implement it?

    Fair enough if I did but I can assure you this was an idea that I had to solve a problem I had. I did not go and look for anything as I wanted to solve this issue myself and come up with a solution. If you think otherwise then you are open to your oppinion.

    Cheers
    Stefan

  • Stefan, I'm sorry for what I thought.
    actually when i was browsing Google results for the c# string enum i got ur link as well codeproject one.

    Thanks for the solution it saved me so much time. and thank u for sharing it with us it is really a genius idea.

    Tarek Jajeh

  • Tarek,

    I can see where you were coming from. They look like the same solution. I am amazed myself. It is just something I thought of and did, and it turns out it had already been done, shoulda googled and saved myself the trouble :P but its good to solve things yourself sometimes.

    Cheers
    Stefan

  • Why not using ToString/Parse methods of standard C# enum?

  • How would you propose this working to solve this issue?

  • Valid points, but it is called StringValue which is pretty specific to what it does, and if you read the post I state the following:

    "I am currently making a Virtual Earth asp.net ajax server control and came to the point where I had to replicate the enums in my classes, but the issue with them is that the enums do not use integer values but string ones. "

    The reason for this is that the Virtual Earth library at the time of creating this has string based values for it's enumerations I needed a way to make nice enumerations that could also contain the string based value, this did this for me.

    Thanks
    Stefan

  • what "using" statments are required for this code to work? I can't seem to compile it (all I have is one line at the top "using System;")

  • using System.Reflection will be needed as well. I would suggest you try Resharper (http://www.jetbrains.com/resharper/) a tool like this will make life easy as it will help you add the required using statements for example, saving headache and time :)

    Cheers
    Stefan

  • I had a similar situation where I needed to loop though a string array of property names in my object, in this case they were DateTime properties and did it the following way. I used this as a helper method to build my insert sql and not include those properties with a null date. The important part is inside the loop

    private string[] getNullableDateColumnsAndValues()
    {
    string columns = "AGENT_EFF_DT,AGENT_TERM_DT,AGENT_1ST_APPT_DT,BANK_DT,SELECT_START_DT,SELECT_END_DT,MUTUAL_DT,REGCD_DT,JUMBOCD_DT,TRANS_DT";
    string[] tmpArray = columns.Split(',');
    string buildColumnValues = string.Empty;
    string buildColumns = string.Empty;
    string[] returnArray = new string[2];

    Type type = this.GetType();

    foreach (string tmpStr in tmpArray)
    {
    DateTime dtProperty = (DateTime)type.InvokeMember(tmpStr, BindingFlags.GetProperty, null, this, null);

    if (dtProperty.Year != 1)
    {
    buildColumnValues += "'" + dtProperty.ToString("d") + "',";
    buildColumns += tmpStr + ",";
    }
    }

    //remove end comma
    if (!buildColumns.Equals(string.Empty))
    {
    buildColumnValues = buildColumnValues.Remove(buildColumnValues.Length - 1);
    buildColumns = buildColumns.Remove(buildColumns.Length - 1);
    }

    returnArray[0] = buildColumnValues;
    returnArray[1] = buildColumns;
    return returnArray;
    }

  • Something similar that I've used - a little more code but no reflection performance hit:

    enum BookingStatus {
    Attended = 0,
    Partial = 1,
    NoShow = 2,
    TurnedAway = 3,
    Failed = 4,
    OnlineTurnedAway = 5
    }
    static Dictionary BookingStatusNames = new Dictionary(){
    { BookingStatus.Attended , "Attended" },
    { BookingStatus.Partial , "Partial Attended" },
    { BookingStatus.NoShow , "No Show" },
    { BookingStatus.TurnedAway , "Turned Away Late" },
    { BookingStatus.Failed , "Failed Test" },
    { BookingStatus.OnlineTurnedAway ,"Online - Not Complete" }
    };

  • Thanks for this very interesting and useful. I made one ammendment to your code which is support for multiple values being set on a enum (i.e. when using the [Flags] Attribute).

    This allows for multi-value / flag enums to be used.

  • For my use, it was easier to do the following (described in my URL):
    using System;
    using System.Collections.Generic;

    namespace testConsole
    {
    class Program
    {
    static void Main(string[] args)
    {
    string[] stringArr = new string[] { "1", "2", "Text with spaces" };
    string text1;
    string text2;
    string text3;
    IEnumerator stringEnum = Program.makeStringEnum(stringArr);
    stringEnum.MoveNext();
    text1 = stringEnum.Current; stringEnum.MoveNext();
    text2 = stringEnum.Current; stringEnum.MoveNext();
    text3 = stringEnum.Current; stringEnum.MoveNext();
    }

    static IEnumerator makeStringEnum(string[] arr)
    {
    foreach (string str in arr)
    {
    yield return str;
    }
    }
    }
    }

  • Why do you inherit from "int"? It works fine without. Thanks and great implementation.

  • Why don't you just add a Description attribute (using System.ComponentModel) and a write a utility method to read? Very simple.

    Write your enum as follows:

    public enum AppStatus
    {
    [Description("Nothing in here")]
    None = 0,
    [Description("Out of scope")]
    OutOfScope,
    [Description("Oops something went wrong")]
    SomethingWentWrong,
    [Description("We have no idea")]
    NoIdea,
    [Description("Working normally")]
    WorkingAsNormal,
    }

    Then a simple util method to read them using reflection.

    public static String GetEnumDescription(Enum e)
    {
    FieldInfo fieldInfo = e.GetType().GetField(e.ToString());

    DescriptionAttribute[] enumAttributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (enumAttributes.Length > 0)
    {
    return enumAttributes[0].Description;
    }
    return e.ToString();
    }

    AppStatus myAppStatus = AppStatus.WorkingAsNormal;

    string myAppStatusDescription = GetEnumDescription(myAppStatus);

  • Enum.GetName( typeof(Patology), enumPatology)

  • Thanks, this is perfect for me

  • Hi,
    it's exactly what I've looking for :)
    How to do it reverse?
    When I receive string :
    public MyEnum Choos
    {
    get
    {
    string Value = CallCallback();
    return ?????? HOW TO PARSE IT
    }
    }

    enum MyEnum{
    [StringValue("ok: none")]
    None = 0,
    [StringValue("You're switching to partial block!")]
    Partial = 1,
    [StringValue("The system is hidden. Leave it !")]
    Hidden = 2,
    [StringValue("smth4")]
    Closed = 3,
    [StringValue("smth 6")]
    Failed = 4,
    [StringValue("smth 5")]
    isOpen = 5
    }

  • Easy, simple, clean. Thanks for posting this.

  • Thanks for share this one.

    Its awesome.

    Once again thanks

  • any performance issue here? when i use the GetstringValue

  • Thanks alot! it helped me alot.
    please keep posting like these kind of stuff.

  • So did anyone ever come up with a way to set the enum value from the string value returned from the database?

  • Ian, for reverse approach, I will try with the following.
    In my requirements, I need that just for one enum, that why is not an extension approach, but it may help.

    public static Enumerations.Pages GetPageByUrl(string pageUrl)
    {
    pageUrl = pageUrl.Substring(pageUrl.LastIndexOf('/') + 1);

    foreach (Enumerations.Pages item in Enum.GetValues(typeof(Enumerations.Pages)))
    {
    FieldInfo fieldInfo = typeof(Enumerations.Pages).GetField(item.ToString());
    StringEnumValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
    typeof(StringEnumValueAttribute),
    false) as StringEnumValueAttribute[];
    if (attribs.Length > 0 && attribs[0].Value.Contains(pageUrl))
    return item;
    }

    return Enumerations.Pages._NotAvailable;
    }

    HTH.
    Milton Rodríguez

  • Stefan,

    can I show the selected string attribute for the selected description based on the value similar to:

    Enum.GetName(typeof(MyEnum), myId) would return the selected description for that id.

    cheers

    Davy

  • Hi Its a very good article and exactly the same which I was looking for. Thanks a lot.

  • Hey guys, how do I reversed the code above?

  • Anyone run into to a compiler error: "Extension methods must be defined in a non-generic static class" on public class StringValueAttribute : Attribute section ?? (I'm using .net 3.5)

  • Here's how you'll go the other way around (string to enum value):

    public static object GetEnumStringValue(this string value,
    Type enumType, bool ignoreCase)
    {
    object result = null;
    string enumStringValue = null;
    if (!tipoEnum.IsEnum)
    throw new ArgumentException
    ("enumType should be a valid enum");

    foreach (FieldInfo fieldInfo in enumType.GetFields())
    {
    var attribs =
    fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false)
    as StringValueAttribute[];
    //Get the StringValueAttribute for each enum member
    if (attribs.Length > 0)
    enumStringValue = attribs[0].StringValue;

    if (string.Compare(enumStringValue, value, ignoreCase) == 0)
    result = Enum.Parse(enumType, fieldInfo.Name);
    }
    return result;
    }

Comments have been disabled for this content.

FAQs

Can enums have string values C#? ›

You can even assign different values to each member. The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type. Specify the type after enum name as : type .

How to use enum with string value in C#? ›

Using string-based enums in C# is not supported and throws a compiler error. Since C# doesn't support enum with string value, in this blog post, we'll look at alternatives and examples that you can use in code to make your life easier. The most popular string enum alternatives are: Use a public static readonly string.

Can enums have string values? ›

You can achieve it but it will require a bit of work. Define an attribute class which will contain the string value for enum. Define an extension method which will return back the value from the attribute.

How do you create an enum with a string value? ›

You can create Enum from String by using Enum. valueOf() method. valueOf() is a static method that is added on every Enum class during compile-time and it's implicitly available to all Enum along with values(), name(), and cardinal() methods.

Can enum store string? ›

Note: you cannot set an enum to string as enums can only have integers. The conversion above simply converts an already existing enum into a string. It is set that every enumeration begins at 0.

Are enums always integers? ›

Enumerations are integers, except when they're not - Embedded.com.

How to map a string to an enum in C#? ›

To convert string to enum use static method Enum. Parse. Parameters of this method are enum type, the string value and optionally indicator to ignore case.

How to get enum value based on name in C#? ›

How to get enum variable name by its value in C#?
  1. /// This is used to get Enum name by its value as integer.
  2. private static void GetEnumName()
  3. {
  4. int[] enumValues = new int[] { 0, 1, 3, 5 };
  5. foreach (int enumValue in enumValues)
  6. {
  7. Console.WriteLine(Enum.GetName(typeof(MicrosoftOffice), enumValue));
  8. }
Jan 9, 2019

What is the difference between enum get name and to string? ›

The main difference between name() and toString() is that name() is a final method, so it cannot be overridden. The toString() method returns the same value that name() does by default, but toString() can be overridden by subclasses of Enum. Therefore, if you need the name of the field itself, use name() .

Is enum a number or string? ›

An enum is a special "class" that represents a group of constants (unchangeable variables). Enums come in two flavors string and numeric .

How to store a string in an enum in Java? ›

Java Enum with Strings
  1. Creating Enum with Strings. Java program to create an enum with strings. ...
  2. Iterating over Enum Constants. To iterate over enum list, use values() method on enum type which returns all enum constants in an array. ...
  3. Getting Enum Value. ...
  4. Getting Enum by Name. ...
  5. Reverse Lookup – Get Enum Name from Value.
Dec 9, 2022

What can an enum include? ›

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.

Why is enum not good? ›

They Lack Accountability. To be clear, it's a mistake to assume consensual non monogamy is void of commitment. It's not simply informing your casual hookup of your other casual hookups. For a lot of people, it's being communicative to their partner of what they're doing with their friend with benefits or boyfriend.

References

Top Articles
Latest Posts
Article information

Author: Saturnina Altenwerth DVM

Last Updated: 08/11/2023

Views: 6103

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Saturnina Altenwerth DVM

Birthday: 1992-08-21

Address: Apt. 237 662 Haag Mills, East Verenaport, MO 57071-5493

Phone: +331850833384

Job: District Real-Estate Architect

Hobby: Skateboarding, Taxidermy, Air sports, Painting, Knife making, Letterboxing, Inline skating

Introduction: My name is Saturnina Altenwerth DVM, I am a witty, perfect, combative, beautiful, determined, fancy, determined person who loves writing and wants to share my knowledge and understanding with you.