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?
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.")
}
I think in simple terms:
Enums is one "type definition", .NET use Reflection when "type descriptor navigation" is needed.
So Enums is a Type and @ runtime, if you want to count the defined enums voice you need to user a 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.
Here is the mistake in your reasoning: Yes, the count of enums cannot be changed during runtime. However, it can be changed between runtime:
A.dll - version 1
public enum Foo { A }
A.dll - version 2
public enum Foo { Bar, Baz }
Replace version 1 of A.dll with version 2. The count of enums has changed (and the names of the values as well).
Why does C# have to use reflection to get the count of enums? Why can't it do so during compile time?
It could do so. But then you would run into the problem above. The compile-time calculated value could become incorrect.
链接地址: http://www.djcxy.com/p/91138.html上一篇: 承诺的重新定义
下一篇: 为什么我在编译期间无法获得枚举数?