59

This is a valid enum

public enum myEnum
{
  a= 1,
  b= 2,
  c= 3,
  d= 4,
  e= 5,
  f= 6,
  g= 7,
  h= 0xff
};

But this is not

public enum myEnum
{
  1a = 1,
  2a = 2,
  3a = 3,
};

Is there a way I can use an number in a enum? I already have code that would populate dropdowns from enums so it would be quite handy

5
  • No idea why the code tags messed up on this one - sorry! Commented Oct 12, 2010 at 16:31
  • 9
    Variable names cannot start with number. This being said it is not clear why do you need something like this so cannot provide helpful answer. Commented Oct 12, 2010 at 16:32
  • Duplicate question... stackoverflow.com/questions/2952192/… Commented Oct 12, 2010 at 16:32
  • @DanPuzey its not a proper original, though it looks like. Commented Jun 8, 2013 at 21:36
  • I would probably use _1, _2, _3 Commented Mar 10, 2020 at 8:38

8 Answers 8

101

No identifier at all in C# may begin with a number (for lexical/parsing reasons). Consider adding a [Description] attribute to your enum values:

public enum myEnum
{
    [Description("1A")]
    OneA = 1,
    [Description("2A")]
    TwoA = 2,
    [Description("3A")]
    ThreeA = 3,
};

Then you can get the description from an enum value like this:

((DescriptionAttribute)Attribute.GetCustomAttribute(
    typeof(myEnum).GetFields(BindingFlags.Public | BindingFlags.Static)
        .Single(x => (myEnum)x.GetValue(null) == enumValue),    
    typeof(DescriptionAttribute))).Description

Based on XSA's comment below, I wanted to expand on how one could make this more readable. Most simply, you could just create a static (extension) method:

public static string GetDescription(this Enum value)
{
    return ((DescriptionAttribute)Attribute.GetCustomAttribute(
        value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static)
            .Single(x => x.GetValue(null).Equals(value)),
        typeof(DescriptionAttribute)))?.Description ?? value.ToString();
}

It's up to you whether you want to make it an extension method, and in the implementation above, I've made it fallback to the enum's normal name if no [DescriptionAttribute] has been provided.

Now you can get the description for an enum value via:

myEnum.OneA.GetDescription()
Sign up to request clarification or add additional context in comments.

2 Comments

Nice Solution; but is there an easier way to retreive the description shorter than these 4 lines ?
Should also point out that it's not limited to Enums, you can use it for anything you apply the DescriptionAttirbute to.
14

No, there isn't. C# does not allow identifiers to start with a digit.

Application usability note: In your application you should not display code identifiers to the end-user anyway. Think of translating individual enumeration items into user-friendly displayable texts. Sooner or later you'll have to extend the enum with an item whose identifier won't be in a form displayable to the user.

UPDATE: Note that the way for attaching displayable texts to enumeration items is being discusses, for example, here.

2 Comments

You can use DescriptionAttribute to associate a user-friendly string with each enum value and populate your dropdowns by extracting the attribute values instead of showing the raw enums.
I needed to define an enumeration for printer types that are 58MM and 80MM. These are user friendly displayable texts :P. Nevertheless, solved with _58mm
10

An identifier in C# (and most languages) cannot start with a digit.

If you can modify the code that populates a dropdown with the enumeration names, you could maybe have a hack that strips off a leading underscore when populating the dropdown and define your enum like so:

public enum myEnum
{
  _1a = 1,
  _2a = 2,
  _3a = 3
};

Or if you don't like the underscores you could come up with your own 'prefix-to-be-stripped' scheme (maybe pass the prefix to the constructor or method that will populate the dropdown from the enum).

Comments

8

Short and crisp 4 line code.

We simply use enums as named integer for items in code,

so any simplest way is good to go.

public enum myEnum
{
    _1 = 1,
    _2,
    _3,
};

Also for decimal values,

public enum myEnum
{
    _1_5 = 1,
    _2_5,
    _3_5,
};

So while using this in code,

int i = cmb1.SelectedIndex(0); // not readable
int i = cmb1.SelectedIndex( (int) myEnum._1_5); // readable

7 Comments

Can you explain how (int) myEnum._1_5 is more readable than 0? And to start with, they're not equivalent in your code. It seems like it makes things hard to understand to me.
_1_5 in a remote code can be understood as 1.5, but 0 cannot be understood as 1.5. Thats how
You're saying that you have a number, 1.5, in an array at position 0, so the most readable way to access the 1.5 is to do array[(int)myEnum._1_5]? That's crazy. If at compile-time you knew you needed 1.5 then double value = 1.5; is far better than double value = array[(int)myEnum._1_5];. Please tell me in what circumstance this increase in verbosity and indirection make sense?
I have a dropdown which has border values for line in PowerPoint which has values like 1, 1.5, 3, 5 etc which I store in enum. So it's easy for me to get/set index based on these value
I think I'd have to see your code to understand why it's useful.
|
4

No way. A valid identifier (ie a valid enumeration member) cannot start with a digit.

Comments

4

Enumerations are no different than variables in terms of naming rules. Therefore, you can't start the name with a number. From this post, here are the main rules for variable naming.

  • The name can contain letters, digits, and the underscore character (_).

    • The first character of the name must be a letter. The underscore is also a legal first character, but its use is not recommended at the beginning of a name. An underscore is often used with special commands, and it's sometimes hard to read.

    • Case matters (that is, upper- and lowercase letters). C# is case-sensitive; thus, the names count and Count refer to two different variables.

    • C# keywords can't be used as variable names. Recall that a keyword is a word that is part of the C# language. (A complete list of the C# keywords can be found in Appendix B, "C# Keywords.")

1 Comment

Better yet, the C# Language Specification section on Identifiers: msdn.microsoft.com/en-us/library/aa664670(v=VS.71).aspx
4

Identifiers can't start with numbers. However, they can contain numbers.

Comments

-3

Here is what i came up with as an alternative, where I needed Enums to use in a "for" Loop and a string representation equivalent to use in a Linq query.

  1. Create enums namespace to be used in "for" Loop.
public enum TrayLevelCodes
    {
        None,
        _5DGS,
        _5DG,
        _3DGS,
        _3DG,
        _AADC,
        _ADC,
        _MAAD,
        _MADC
    };
  1. Create strings based on enum created to be used for Linq query
public string _5DGS = "\"5DGS\"",
        _5DG = "\"5DG\"",
        _3DGS = "\"3DGS\"",
        _3DG = "\"3DG\"",
        _AADC = "\"AADC\"",
        _ADC = "\"ADC\"",
        _MAAD = "\"MAAD\"",
        _MADC = "\"MADC\"";
  1. Create function that will take an enum value as argument and return corresponding string for Linq query.
public string GetCntnrLvlDscptn(TrayLevelCodes enumCode)
        {
            string sCode = "";
            switch (enumCode)
            {
                case TrayLevelCodes._5DGS:
                    sCode = "\"5DGS\"";
                    break;
                case TrayLevelCodes._5DG:
                    sCode = "\"5DG\"";
                    break;
                case TrayLevelCodes._3DGS:
                    sCode = "\"3DGS\"";
                    break;
                case TrayLevelCodes._3DG:
                    sCode = "\"3DG\"";
                    break;
                case TrayLevelCodes._AADC:
                    sCode = "\"AADC\"";
                    break;
                case TrayLevelCodes._ADC:
                    sCode = "\"AAC\"";
                    break;
                case TrayLevelCodes._MAAD:
                    sCode = "\"MAAD\"";
                    break;
                case TrayLevelCodes._MADC:
                    sCode = "\"MADC\"";
                    break;
                default:
                    sCode = "";
                    break;
            }
                return sCode;
        }
  1. Here is how i am using what i created above.
for (var trayLevelCode = TrayLevelCodes._5DGS; trayLevelCode <= TrayLevelCodes._MADC; trayLevelCode++)
{
    var TrayLvLst = (from i in pair1.Value.AutoMap
                     where (i.TrayLevelCode == HTMLINFO.GetCntnrLvlDscptn(trayLevelCode))
                     orderby i.TrayZip, i.GroupZip
                     group i by i.TrayZip into subTrayLvl
                     select subTrayLvl).ToList();
    foreach (DropShipRecord tray in TrayLvLst)
    {

    }
}

1 Comment

It'd be a lot easier to just use the Description attribute.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.