lte__
lte__

Reputation: 7593

Enum with int value?

I want to make an enum for possible grades. This is a working example:

public enum Grade
{
    A, B, C, D, E, F
}

However, I want the grades to be integers, like

public enum Grade
{
    1, 2, 3, 4, 5
}

Why does the first one work but not the second? How can I make a similar variable that can only take values from 1-5 (and is nullable)?

Upvotes: 6

Views: 13378

Answers (5)

InBetween
InBetween

Reputation: 32790

How can I make a similar variable that can only take values from 1-5 (and is nullable)?

Make your own type:

public struct Grade: IEquatable<Grade>
{
    private int innerValue;
    private int InnerValue => isInitialized ? innerValue : 1;
    private readonly bool isInitialized;

    private Grade(int value)
    {
        if (value < 1 || value > 5)
            throw new OverflowException();

        innerValue = value;
        isInitialized = true;
    }

    public static implicit operator Grade(int i) => new Grade(i);
    public static explicit operator int(Grade g) =>  g.InnerValue;
    public override bool Equals(object obj) => obj is Grade && Equals((Grade)obj);
    public bool Equals(Grade other) => InnerValue == other.InnerValue;
    public override int GetHashCode() => InnerValue.GetHashCode();
    public override string ToString() => InnerValue.ToString();
    public static bool operator ==(Grade left, Grade right) => left.Equals(right);
    public static bool operator !=(Grade left, Grade right) => !left.Equals(right);
}

Now you have a type than can only hold 1, 2, 3, 4 and 5 and defaults to 1. Initializing it is as simple as Grade g = 4;.

You need it to be nullable? No sweat: Grade? g = 4;.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727137

C# requires enum constants to be identifiers, i.e. start in a letter/underscore, and include only letters, underscores, and digits.

You have multiple options to deal with this:

  • Spell out the numbers - i.e. Grade.One, Grade.Two, etc.
  • Prefix the number with a letter, or
  • Prefix the number with an underscore.

In my opinion, the first option is the best, because it reads very well:

enum Grade {
    One = 1
,   Two
,   Three
,   Four
,   Five
}

The last option looks odd, but if you your mind is absolutely set on using numbers, this is as close as you can get to it:

enum Grade {
    _1 = 1 // Without =1 the value of _1 would be zero
,   _2
,   _3
,   _4
,   _5
}

Upvotes: 5

STLDev
STLDev

Reputation: 6174

As others have said, the names you want to use for your enum of {1, 2, 3, etc} are invalid because they're not valid C# identifiers.

If you need those values out of your enum, you can do the following:

// Declare enum
public enum Grade
{
    A = 1,
    B,
    C,
    D,
    F
}

Then, when you need to access the value of say, Grade.B, you can do that like this:

int theIntGrade = (int)Grade.B  // after this line, theIntGrade will be equal to 2

Note that if you had a grade as a string, such as "C", you could convert it into an enumeration value like this:

Grade theLetterGrade = (Grade)Enum.Parse(typeof(Grade), "C", true); // final parameter sets case sensitivity for comparison

Upvotes: 0

labilbe
labilbe

Reputation: 3594

You should specify Grade like this.

public enum Grade
{
    A = 1,
    B,
    C,
    D,
    E,
    F
}

B, C and so on will take next value.

Upvotes: 11

Marc Gravell
Marc Gravell

Reputation: 1064324

enum elements need to have valid C# identifiers; 1, 2, 3 etc are not valid C# identifiers, so no: you can't do that. You can perhaps use One = 1 etc, or some common prefix (Grade1), but...

Upvotes: 9

Related Questions