Joan Venge
Joan Venge

Reputation: 330992

Possible to have strings for enums?

I want to have an enum as in:

enum FilterType
{
   Rigid = "Rigid",
   SoftGlow = "Soft / Glow",
   Ghost = "Ghost",
}

How to achieve this? Is there a better way to do this? It's gonna be used for an instance of an object where it's gonna be serialized/deserialized. It's also gonna populate a dropdownlist.

Upvotes: 7

Views: 615

Answers (12)

Malfist
Malfist

Reputation: 31795

No, but you can cheat like this:

public enum FilterType{
   Rigid,
   SoftGlow,
   Ghost
}

And then when you need their string values you can just do FilterType.Rigid.ToString().

Upvotes: 2

scottmgerstl
scottmgerstl

Reputation: 765

It is not outright possible. However you can fake it using an array.

First, Create you enum the way you would a regular one:

public enum Regexs
{ 
   ALPHA = 0, 
   NUMERIC = 1, 
   etc.. 
}

Then you create an array that holds the values corresponding to the enum values:

private static string[] regexs = new string[]
{
   "[A-Za-z]",
   "[0-9]",
   "etc"...
}

Then you can access your strings through the enum value:

public void runit(Regexs myregexEnum)
{
    Regex regex = new Regex( regexs [(int)myregexEnum] );
}

Upvotes: 1

bobbymcr
bobbymcr

Reputation: 24167

This is not possible. C# only allows integral enum types (int, short, long, etc.). You can either create a lightweight "enum-like" class or use static constants.

static class FilterTypes
{
    public const string Rigid = "Rigid";
    // ...
}

// or ...

class FilterType
{
    static readonly FilterType RigidFilterType = new FilterType("Rigid");

    string name;

    FilterType(string name)  // private constructor
    {
        this.name = name;
    }

    public static FilterType Rigid
    {
        get { return FilterType.RigidFilterType; }
    }

    // ...
}

Upvotes: 1

Michael Gattuso
Michael Gattuso

Reputation: 13200

Along the lines of Shaun Bowe's example you can also do this in C# 3 with an extension method for enum (I did not come up with and cannot, for the life of me, remember where I did).

Create an Attribute:

public class DisplayTextAttribute : Attribute {
  public DisplayTextAttribute(String text) {
  Text = text;
  }
  public string Text { get; set; }
}

Create an extension:

public static class EnumHelpers {
  public static string GetDisplayText(this Enum enumValue) {
    var type = enumValue.GetType();
    MemberInfo[] memberInfo = type.GetMember(enumValue.ToString());

    if (memberInfo == null || memberInfo.Length == 0)
      return enumValue.ToString();

    object[] attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayTextAttribute), false);
    if (attributes == null || attributes.Length == 0)
      return enumValue.ToString();

    return ((DisplayTextAttribute)attributes[0]).Text;
  }
}

I've found this to be really tidy solution. In your enum add the following:

enum FilterType{
  Rigid,
  [DisplayText("Soft / Glow")]
  SoftGlow,
  Ghost
}

You could then access FilterType.GetDisplayText() which will pull back the string for the unattributed enums and the displayText for the ones with attributes.

Upvotes: 0

Mark Carpenter
Mark Carpenter

Reputation: 17775

If you're comfortable with extension methods, you can easily do what you're after:

//Can return string constants, the results of a Database call, 
//or anything else you need to do to get the correct value 
//(for localization, for example)
public static string EnumValue(this MyEnum e) {
    switch (e) {
        case MyEnum.First:
            return "First Friendly Value";
        case MyEnum.Second:
            return "Second Friendly Value";
        case MyEnum.Third:
            return "Third Friendly Value";
    }
    return "Horrible Failure!!";
}

This way you can do:

Private MyEnum value = MyEnum.First;
Console.WriteLine(value.EnumValue());

Upvotes: 2

CSharpAtl
CSharpAtl

Reputation: 7512

You can use an Attribute over the values

[System.ComponentModel.Description("Rigid")]

example:

 enum FilterType
{
   [System.ComponentModel.Description("Rigid")]
   Rigid,
    [System.ComponentModel.Description("Soft / Glow")]
   SoftGlow,
    [System.ComponentModel.Description("Ghost")]
   Ghost
}

and use Reflection to get the descriptions.

Enum extension method:

public static string GetDescription(this Enum en)
    {
        var type = en.GetType();
        var memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {
            var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }
        return en.ToString();
    }

use it:

FilterType = FilterType.Rigid;
            string description= result.GetDescription();

Upvotes: 0

Josh Bush
Josh Bush

Reputation: 2718

In the System.ComponentModel namespace there is a class DescriptionAttribute that works well here.

enum FilterType
{
   Rigid,
   [Description("Soft / Glow")]
   SoftGlow,
   Ghost,
}

Then to get the description and fail over to the ToString()

var descriptionAttribute = Value.GetType()
 .GetField(Value.ToString())
 .GetCustomAttributes(typeof(DescriptionAttribute), false)
 .OfType <DescriptionAttribute>()
 .FirstOrDefault()??new DescriptionAttribute(Value.ToString());

Upvotes: 1

Shaun Bowe
Shaun Bowe

Reputation: 10008

using System.ComponentModel;   
enum FilterType
{
    [Description("Rigid")]
    Rigid,
    [Description("Soft / Glow")]
    SoftGlow,
    [Description("Ghost")]
    Ghost ,
}

You can get the value out like this

public static String GetEnumerationDescription(Enum e)
{
  Type type = e.GetType();
  FieldInfo fieldInfo = type.GetField(e.ToString());
  DescriptionAttribute[] da = (DescriptionAttribute[])(fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false));
  if (da.Length > 0)
  {
    return da[0].Description;
  }
  return e.ToString();
}

Upvotes: 11

Joey
Joey

Reputation: 2951

You can get the Enum name as a string like this

FilterType myType = FilterType.Rigid;
String strType = myType.ToString();

However, you may be stuck with the Camel Case/Hungarian notation, but you can easily convert that to a more user friendly String using a method like this (Not the prettiest solution, I would be grateful for input on optimizing this):

Public Shared Function NormalizeCamelCase(ByVal str As String) As String

    If String.IsNullOrEmpty(str) Then
        Return String.Empty
    End If

    Dim i As Integer = 0
    Dim upperCount As Integer = 0
    Dim otherCount As Integer = 0
    Dim normalizedString As String = str

    While i < normalizedString.Length

        If Char.IsUpper(normalizedString, i) Then
            ''Current char is Upper Case
            upperCount += 1
            If i > 0 AndAlso Not normalizedString(i - 1).Equals(" "c) Then
                ''Current char is not first and preceding char is not a space
                ''...insert a space, move to next char
                normalizedString = normalizedString.Insert(i, " ")
                i += 1
            End If
        ElseIf Not Char.IsLetter(normalizedString, i) Then
            otherCount += 1
        End If

        ''Move to next char
        i += 1

    End While

    If upperCount + otherCount = str.Length Then
        ''String is in all caps, return original string 
        Return str
    Else
        Return normalizedString
    End If

End Function

If that's still not pretty enough, you may want to look into Custom Attributes, which can be retrieved using Reflection...

Upvotes: 1

Dave Markle
Dave Markle

Reputation: 97691

No, but if you want to scope "const" strings and use them like an enum, here's what I do:

public static class FilterType
{
   public const string Rigid = "Rigid";
   public const string SoftGlow =  "Soft / Glow";
   public const string Ghost ="Ghost";
}

Upvotes: 9

Etienne Brouillard
Etienne Brouillard

Reputation: 281

Enums are always linked to an integer value. So no. You can do FilterType.Rigid.ToString() to obtain the string value although it can't be localized directly.

Upvotes: 1

Michael Petrotta
Michael Petrotta

Reputation: 60902

No, it's not possible.

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

However, you can retrieve the declared name of an enum with the Enum class:

string name = Enum.GetName(typeof(FilterType), FilterType.Rigid);

If this doesn't work for you, a collection of string constants collected in a class might.

Upvotes: 0

Related Questions