Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I get the count of enums during compile time?

I have asked How can I get the number of enums as a constant?, and I found out that I cannot get the count of enums during compile time, because C# uses reflection to do so.

I read What is reflection and why is it useful?, so I have a very basic understanding of reflection.

To get the count of enums, I can use Enum.GetNames(typeof(Item.Type)).Length;, and this happens during runtime using reflection.

I don't see any runtime knowledge needed to get the count of enums, because as far as I know, the count of enums cannot be changed during runtime.

Why does C# have to use reflection to get the count of enums? Why can't it do so during compile time?

like image 437
Evorlor Avatar asked Apr 06 '16 14:04

Evorlor


People also ask

How do you find the length of an enum?

To get the length of an enum: Use the Object. keys() method to get an array containing the enum's keys. Access the length property on the array.

How do I get the length of an enum in unity?

Here is the C# version : _primaryAttribute = new Attribute( Enum. GetValues( typeof(AttributeName) ). Length );

Should enums be numbers?

Enums are always assigned numeric values when they are stored. The first value always takes the numeric value of 0, while the other values in the enum are incremented by 1.

What number do enums start with?

Enum Values The first member of an enum will be 0, and the value of each successive enum member is increased by 1.


1 Answers

Just because something can be evaluated at compile time doesn't mean that someone has programmed the compiler to do so. string.Format("{0:N2}", Math.PI) is another example.

The only way at present to get the count of the number of values of an Enum is by using reflection (Enum.GetNames or something similar). So it is not a constant expression, although technically the compiler could just evaluate the expression at compile-time and determine what the result is.

nameof is a perfect example. It is constant at compile-time, but there was no mechanism to extract the result at compile time until someone designed, developed, tested, documented, and shipped the feature. None of those are free, and thus the idea must compete for valuable resources (people, time, money) against other features that may be more valuable.

So if you feel that a compile-time construct like enumcount(Item.Type) is a valuable addition to the language, then you are more than welcome to post a suggestion on Connect and see if it makes it to the top of the feature list.

But, I need this number as a constant number, so that I can use it in Unity's [Range(int, int)] feature.

One non-ideal workaround is to define a constant that matches the current number of enum items, and throw an exception at run-time if the counts do not match:

Define a public constant right next to your enum, commenting it so that developers know to update it:

// Update this value any time the Type enum is updated
public const int TypeCount = 5;
public Enum Type
{
    Bar1,
    Bar2,
    Bar3,
    Bar4,
    Bar5,
}

use it in your attribute:

[Range(0, Item.TypeCount)]
public void BlahBlahBlah() {}

and check it at the start of your app:

public static Main()
{
   if(Enum.GetNames(typeof(Item.Type)).Length != Item.TypeCount)
      throw new ApplicationException ("TypeCount and number of Types do not match.\nPlease update TypeCount constant.")
}
like image 120
D Stanley Avatar answered Oct 18 '22 19:10

D Stanley