为什么我不能在编译期间获得枚举数?

Evo*_*lor 7 c# reflection enums count compile-time

我问过如何将枚举数量作为常量?,我发现在编译期间我无法获得枚举数,因为C#使用反射来实现.

我读了什么是反射,为什么它有用?所以我对反思有一个非常基本的理解.

为了得到枚举的数量,我可以使用Enum.GetNames(typeof(Item.Type)).Length;,这在运行时使用反射发生.

我没有看到获取枚举计数所需的任何运行时知识,因为据我所知,在运行时期间无法更改枚举的数量.

为什么C#必须使用反射来获取枚举数?为什么不能在编译期间这样做?

D S*_*ley 5

仅仅因为某些东西可以在编译时被评估并不意味着有人已经对编译器进行了编程来这样做。 string.Format("{0:N2}", Math.PI)是另一个例子。

目前获得 an 值数量的唯一方法Enum是使用反射(Enum.GetNames或类似的东西)。所以它不是一个常量表达式,尽管从技术上讲,编译器可以在编译时评估表达式并确定结果是什么。

nameof是一个完美的例子。它在编译时保持不变,但在有人设计、开发、测试、记录和发布该功能之前,没有机制可以在编译时提取结果。这些都不是免费的,因此这个想法必须与其他可能更有价值的功能竞争有价值的资源(人员、时间、金钱)。

因此,如果您觉得像这样的编译时构造enumcount(Item.Type)是该语言的一个有价值的补充,那么非常欢迎您在Connect上发表建议,看看它是否在功能列表的顶部。

但是,我需要这个数字作为一个常数,以便我可以在 Unity 的 [Range(int, int)] 功能中使用它。

一种非理想的解决方法是定义一个与当前枚举项数匹配的常量,如果计数不匹配,则在运行时抛出异常:

在枚举旁边定义一个公共常量,对其进行评论,以便开发人员知道更新它:

// Update this value any time the Type enum is updated
public const int TypeCount = 5;
public Enum Type
{
    Bar1,
    Bar2,
    Bar3,
    Bar4,
    Bar5,
}
Run Code Online (Sandbox Code Playgroud)

在您的属性中使用它:

[Range(0, Item.TypeCount)]
public void BlahBlahBlah() {}
Run Code Online (Sandbox Code Playgroud)

并在您的应用程序开始时检查它:

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.")
}
Run Code Online (Sandbox Code Playgroud)


小智 0

我认为简单来说:

枚举是一种“类型定义”,.NET 在需要“类型描述符导航”时使用反射。

所以Enums是一个Type和@runtime,如果你想对定义的enum声音进行计数,你需要使用反射。