63

Possible Duplicate:
Enum with strings

Is it possible to have string constants in enum like the following?

      enum{name1="hmmm" name2="bdidwe"}

If it is not, what is the best way to do so?

I tried it, but it's not working for string so right now I am grouping all related constants in one class like

      class operation
      {
          public const string  name1="hmmm";
          public const string  name2="bdidwe"
      }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Maddy.Shik
  • 6,609
  • 18
  • 69
  • 98
  • Exact duplicate of http://stackoverflow.com/questions/630803/enum-with-strings – Jonatan Lindén Dec 05 '09 at 08:51
  • string[] Days = { "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه", "شنبه", }; int i =(int) obj.GetDayOfWeek(dt); string DayName = Days[i]; – Samiey Mehdi Jul 19 '13 at 21:13

4 Answers4

122

Enum constants can only be of ordinal types (int by default), so you can't have string constants in enums.

When I want something like a "string-based enum" I create a class to hold the constants like you did, except I make it a static class to prevent both unwanted instantiation and unwanted subclassing.

But if you don't want to use string as the type in method signatures and you prefer a safer, more restrictive type (like Operation), you can use the safe enum pattern:

public sealed class Operation
{
    public static readonly Operation Name1 = new Operation("Name1");
    public static readonly Operation Name2 = new Operation("Name2");

    private Operation(string value)
    {
        Value = value;
    }

    public string Value { get; private set; }
}
burnside
  • 2,551
  • 23
  • 20
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 1
    This one seems really awesome.thanks – Maddy.Shik Dec 05 '09 at 09:35
  • 24
    +1 Fit perfectly. Add to that implicit operations, and you're golden: `public static implicit operator string(Operation op) { return op.Value; }` because then you can use it as a strongly typed parameter, or as a string. – Dave T. Feb 01 '13 at 19:06
  • 2
    But it's not possible to use the above pattern where string constants are required, for example, in switch..case statements – ghd Aug 07 '14 at 04:31
  • why not just enum.ToString("F") ? – GL_monk-342435 Jun 04 '15 at 21:04
  • 1
    @ghanashyaml I believe that relies on reflection. It's slow in any case. – MarioDS Feb 17 '16 at 10:05
  • Great pattern! I also added to this class: public override string ToString() { return this.Value; } – lukiller Feb 24 '17 at 20:46
  • @MarioDS it uses a virtual function table lookup, not reflection. So it's a lot faster than reflection, but not as fast as a plain old property getter. – AJ Richardson May 20 '17 at 00:51
  • Why not using `public static readonly string Name1 = new Operation("Name1").Value;`. Thus avoiding to need to use the Value property when in need of the string. E.g. instead of `Operation.Name1.Value` use `Operation.Name1`. – Janis S. Jul 18 '17 at 20:13
  • 1
    @Janis As stated in the answer: "if you don't want to use string as the type in method signatures and you prefer a safer, more restrictive type" – R. Martinho Fernandes Jul 19 '17 at 12:39
  • This helped a lot, But how do I write a generic Equal() for classes like above. Ex: to check `Operation.Name1 == "Name1"` – djkpA Aug 30 '17 at 10:16
  • How to get the full list or an array of `Operation`? – Andrei Krasutski Jul 12 '19 at 08:05
  • Wouldn't it be easier use a stuct? – LordDraagon Oct 07 '22 at 13:14
44

You could do this using DescriptionAttribute, but then you'd have to write code to get the string out of the attribute.

public enum YourEnum
{
    [Description("YourName1")]
    Name1,

    [Description("YourName2")]
    Name2
}
Taylor Leese
  • 51,004
  • 28
  • 112
  • 141
  • 4
    +1 First time coming across Description attribute. Thanks :) –  Dec 05 '09 at 09:22
  • How to get string out of attribute? – Maddy.Shik Dec 05 '09 at 09:46
  • +1 the only answer yet that has taken the position that the OP's intent is to have something that has the full range of possibilities of an Enum type. – BillW Dec 05 '09 at 10:47
  • 1
    There's a number of examples if you google "enum descriptionattribute". Here's one: http://weblogs.asp.net/grantbarrington/archive/2009/01/19/enumhelper-getting-a-friendly-description-from-an-enum.aspx – Taylor Leese Dec 05 '09 at 12:24
  • 1
    This is a good answer to the question +1, but in practice this attribute is terribly vague as to its function and probably not that helpful in practice – mungflesh Nov 05 '13 at 09:39
  • +1 for it's simplicity. – Ashok kumar Jun 10 '14 at 10:30
  • Description did not work for me! Don't know why. Instead Display(Name = "String value") worked for me when I was working with Drop Down List. But thank you so much, I got the idea from you. Very nice and simple solution. – InsParbo Nov 14 '16 at 06:23
  • Description did not work for me meaning in the drop down list, it does not show the description! Instead Display(Name = "String value") worked for me when I was working with Drop Down List. But when getting index view, it does not show the display name! – InsParbo Nov 14 '16 at 07:12
11

The whole point of enums is to be ordinal constants.
However, you can achieve what you want by using an extension method:

  enum Operation
  {
      name1,
      name2
  }

  static class OperationTextExtender
  {
        public static String AsText(this Operation operation)
        {
              switch(operation)
              {
                    case Operation.name1: return "hmmm";
                    case Operation.name2: return "bdidwe";
                    ...
              }
        }
  }

  ...
  var test1 = Operation.name1;
  var test2 = test1.AsText();   
Robert Giesecke
  • 4,314
  • 21
  • 22
  • I really wonder if you would ever use a one-off extension method like this in real-world code ? (there's no sarcasm intended in that question). It is interesting to know this could be done. – BillW Dec 05 '09 at 09:16
  • I have a snippet that creates extension classes with a Contains and Remove method for flag enums. I don't want it to be part of the public API, so it is internal. But I use it fairly frequently and for built-in flags as well, particularly "Contains". – Robert Giesecke Dec 06 '09 at 15:16
  • @RobertGiesecke Just wanted to give you Kudos for this solution. The extension method was a perfect and elegant way for me to do this! The other solutions were to avoid enums but this solution allowed me to extend and it worked perfect without having to go overboard in complicating the task as most of the solutions did.. – Mike Dec 17 '17 at 19:10
0

Your operation class won't compile as is... you didn't declare the type of name1 and name2...

But that is the approach I'd take... yes.

If you make it a struct then it becomes a value type which may or may not be what you wanted...

John Weldon
  • 39,849
  • 11
  • 94
  • 127