425

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

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
Rashmi Pandit
  • 23,230
  • 17
  • 71
  • 111

12 Answers12

582

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;
Bakudan
  • 19,134
  • 9
  • 53
  • 73
Kasper Holdum
  • 12,993
  • 6
  • 45
  • 74
  • 1
    Agreed ... here's a link i found http://www.csharp411.com/c-count-items-in-an-enum/ – Rashmi Pandit May 13 '09 at 05:45
  • 13
    Could also use Enum.GetValues. – Xonatron Nov 25 '14 at 07:52
  • 6
    System.Enum.GetNames, if you aren't already including the System namespace. – Brett Pennings Feb 03 '15 at 02:55
  • 9
    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. – J Trana Jun 19 '16 at 20:58
  • @Xonatron `GetNames` performs about 10 times faster than `GetValues` in my tests, I wonder why. – saastn Feb 20 '21 at 20:07
  • 2
    @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. – atkins Sep 02 '21 at 15:09
197

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();
Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
  • 2
    Alternative way of writing the last line, `var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();`. – Jeppe Stig Nielsen Jan 15 '16 at 19:12
  • 14
    I cannot think of any developer I've ever met in my life who'd affirm that such an enum contains 3 items. – motoDrizzt Jun 13 '18 at 07:09
  • 2
    @motoDrizzt 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, ...` ;). – shA.t Dec 27 '18 at 08:08
  • @Timothy Shields, probably would have been better to say _distinct values_ instead of just _values_ – Dave Thompson Feb 09 '22 at 17:29
82

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

Flexo
  • 87,323
  • 22
  • 191
  • 272
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
39

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 |
ENikS
  • 411
  • 4
  • 6
  • 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. – Paul W Mar 27 '23 at 16:24
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.

Josh
  • 632
  • 7
  • 13
10

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.

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
Lucas Willett
  • 399
  • 1
  • 12
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
        }
    }
jvanderh
  • 2,925
  • 4
  • 24
  • 28
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;
}
Matt Parkins
  • 24,208
  • 8
  • 50
  • 59
3

For Visual Basic:

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

idbrii
  • 10,975
  • 5
  • 66
  • 107
S22
  • 65
  • 1
  • Why the downvote? This fixed my problem, it's the correct syntax for VB, even though the question is tagged c#, still useful. – M Granja Apr 20 '15 at 19:50
  • 2
    Downvotes probably because question is tagged C# and this answer didn't mention it wasn't using C#. – idbrii Feb 22 '18 at 19:01
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.

EnergyWasRaw
  • 134
  • 8
  • 3
    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. – BradleyDotNET Nov 12 '14 at 23:08
  • 2
    That didn't take long :) – EnergyWasRaw Nov 12 '14 at 23:10
  • 1
    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! – EnergyWasRaw Nov 12 '14 at 23:12
  • 1
    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.. – Peter Drier Mar 09 '21 at 10:51
0

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

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

Enum.GetNames<>() method

Mustafa Özçetin
  • 1,893
  • 1
  • 14
  • 16
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 :)

noobsee
  • 806
  • 15
  • 29