Total number of items defined in an enum
Asked Answered
A

12

436

How can I get the number of items defined in an enum?

Ascham answered 13/5, 2009 at 5:6 Comment(0)
L
593

You can use the static method Enum.GetNames which returns an array representing the names of all the items in the enum. The length property of this array equals the number of items defined in the enum

var myEnumMemberCount = Enum.GetNames(typeof(MyEnum)).Length;
Ladonna answered 13/5, 2009 at 5:10 Comment(6)
Agreed ... here's a link i found csharp411.com/c-count-items-in-an-enumAscham
Could also use Enum.GetValues.Prakash
System.Enum.GetNames, if you aren't already including the System namespace.Hypsometry
So I just encountered this problem again today; the C style trick as described in other answers below is listed as being problematic but both the Enum.GetValues and Enum.GetNames as listed above seem like they risk allocating a whole new array just to get a fixed length, which seems... well, horrible. Does anyone know if this approach does indeed incur dynamic allocation? If so, for certain use cases it seems far and away the most performant solution if not the most flexible.Watermelon
@Prakash GetNames performs about 10 times faster than GetValues in my tests, I wonder why.Mcculloch
@JTrana Yup, I've just traced some unexpected allocation to exactly this: getting this length repeatedly via Enum.GetNames in a loop condition (it wasn't obvious at a glance because it was in the getter of a property). So at the very least, make sure to cache the value somewhere the first time you get it. It's a shame we can't get at this as a compile-time constant.Midinette
D
199

The question is:

How can I get the number of items defined in an enum?

The number of "items" could really mean two completely different things. Consider the following example.

enum MyEnum
{
    A = 1,
    B = 2,
    C = 1,
    D = 3,
    E = 2
}

What is the number of "items" defined in MyEnum?

Is the number of items 5? (A, B, C, D, E)

Or is it 3? (1, 2, 3)

The number of names defined in MyEnum (5) can be computed as follows.

var namesCount = Enum.GetNames(typeof(MyEnum)).Length;

The number of values defined in MyEnum (3) can be computed as follows.

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();
Despoil answered 5/6, 2013 at 17:44 Comment(4)
Alternative way of writing the last line, var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();.Herringbone
I cannot think of any developer I've ever met in my life who'd affirm that such an enum contains 3 items.Hirsh
@Hirsh you can find something like that at an enum of a printer driver like Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ... ;).Vergara
@Timothy Shields, probably would have been better to say distinct values instead of just valuesIntermit
P
84

Enum.GetValues(typeof(MyEnum)).Length;

Paramaribo answered 13/5, 2009 at 5:9 Comment(2)
It's faster to use the GetNames method.Ladonna
@KasperHoldum Are you running it redundantly in a tight loop or something? Because my next question would be, why?Monteverdi
L
43

I've run a benchmark today and came up with interesting result. Among these three:

var count1 = typeof(TestEnum).GetFields().Length;
var count2 = Enum.GetNames(typeof(TestEnum)).Length;
var count3 = Enum.GetValues(typeof(TestEnum)).Length;

GetNames(enum) is by far the fastest!

|         Method |      Mean |    Error |   StdDev |
|--------------- |---------- |--------- |--------- |
| DeclaredFields |  94.12 ns | 0.878 ns | 0.778 ns |
|       GetNames |  47.15 ns | 0.554 ns | 0.491 ns |
|      GetValues | 671.30 ns | 5.667 ns | 4.732 ns |
Loveridge answered 10/8, 2020 at 21:32 Comment(1)
Careful with DeclaredFields ; on a typed enum, using that method adds an extra "SpecialName" entry containing the type of the Enum (e.g. Int32). That adds one extra count compared to what is expected.Cannady
P
21

A nifty trick I saw in a C answer to this question, just add a last element to the enum and use it to tell how many elements are in the enum:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

In the case where you're defining a start value other than 0, you can use NumberOfTypes - Type1 to ascertain the number of elements.

I'm unsure if this method would be faster than using Enum, and I'm also not sure if it would be considered the proper way to do this, since we have Enum to ascertain this information for us.

Phyllida answered 5/6, 2013 at 17:29 Comment(7)
this is nice since i can do this on XNA because GetNames isn't available thereAgnail
Cool trick, this would also be faster than GetNames() because it doesn't have to count them.Raimondo
Beware of code that cycles through enums via foreach - you can read off the end of your arrays!Accusatory
Also, beware of enums that define their own values - I often use enums for bit flags.Clotildecloture
Also beware of direct enum bindings to some wpf controls such as combobox and listboxHarner
For what it's worth, this is against the Microsoft design guidelines (see the item "DO NOT include sentinel values in enums")Groundsheet
This is textbook code smell right here.Monteverdi
C
11

You can use Enum.GetNames to return an IEnumerable of values in your enum and then. Count the resulting IEnumerable.

GetNames produces much the same result as GetValues but is faster.

Cavalla answered 13/5, 2009 at 5:10 Comment(0)
A
6

From the previous answers just adding code sample.

 class Program
    {
        static void Main(string[] args)
        {
            int enumlen = Enum.GetNames(typeof(myenum)).Length;
            Console.Write(enumlen);
            Console.Read();
        }
        public enum myenum
        {
            value1,
            value2
        }
    }
Airminded answered 13/5, 2009 at 5:6 Comment(0)
C
5

If you find yourself writing the above solution as often as I do then you could implement it as a generic:

public static int GetEnumEntries<T>() where T : struct, IConvertible 
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enumerated type");

    return Enum.GetNames(typeof(T)).Length;
}
Clotildecloture answered 19/9, 2016 at 11:8 Comment(0)
M
4

For Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Length did not work with me, but [Enum].GetNames(GetType(Animal_Type)).length did.

Macey answered 17/8, 2014 at 4:47 Comment(2)
Why the downvote? This fixed my problem, it's the correct syntax for VB, even though the question is tagged c#, still useful.Erectile
Downvotes probably because question is tagged C# and this answer didn't mention it wasn't using C#.Edan
O
1

I was looking into this just now, and wasn't happy with the readability of the current solution. If you're writing code informally or on a small project, you can just add another item to the end of your enum called "Length". This way, you only need to type:

var namesCount = (int)MyEnum.Length;

Of course if others are going to use your code - or I'm sure under many other circumstances that didn't apply to me in this case - this solution may be anywhere from ill advised to terrible.

Outgoing answered 12/11, 2014 at 23:7 Comment(4)
This also relies on the enum starting at 0 (the default, but by no means guaranteed). Additionally, it makes the intellisense for normal enum usage very confusing. This is nearly always a terrible idea.Muster
That didn't take long :)Outgoing
Interesting, I suppose you never know when something better may come about. I made my best attempt at shunning my own solution, but found it interesting enough to share!Outgoing
Arguably this route is the most performant if your use case works with the enum starts with 0 case. But please don't call it "Length".. I use COUNT so it stands out in the intellisense world. I'll often use ERROR as the default value as well, so it's obvious when something hasn't been set in the pre everything can be nullable worlds..Domesticate
B
0

There is a more concise way with the generic GetNames() overload:

int itemCount = Enum.GetNames<MyEnum>().Length;

Enum.GetNames<>() method

Beatrisbeatrisa answered 9/5, 2023 at 12:33 Comment(0)
S
0

If it only to know how many items inside the ENUM. I will do this instead:

enum MyEnum()
{
  FIRST =  0,
  SECOND = 1,

  TOTAL_ENUM_ITEM
}

The last ENUM item MyEnum.TOTAL_ENUM_ITEM will show you the number of items inside the ENUM.

It's not fancy, but it works :)

Scepter answered 31/5, 2023 at 7:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.