枚举.GetValues(typeof(..))未返回正确的枚举值

本文关键字:枚举 GetValues typeof 返回 | 更新日期: 2023-09-27 18:24:55

给定此代码:

public enum Enum1
{
    ONE,
    TWO
}
public enum Enum2
{
    A,
    B
}

此代码返回一,二:

foreach (Enum1 e in Enum.GetValues(typeof(Enum1)))
{
  Console.WriteLine(e);
}

但此代码并没有失败(因为Enum2 etypeof(Enum1)一起使用),而是返回A、B:

foreach (Enum2 e in Enum.GetValues(typeof(Enum1)))
{
    Console.WriteLine(e);
}

为什么?

枚举.GetValues(typeof(..))未返回正确的枚举值

因为在封面下枚举只是int-第二个返回Enum1的值,但实际上这些值只是01。当您将这些值强制转换为类型Enum2时,这些值仍然有效,并对应于值"A"answers"B"。

因为枚举的值是隐式整数:

public enum Enum1
{
    ONE = 0,
    TWO = 1
}
public enum Enum2
{
    A = 0,
    B = 1
}

Enum1的值被隐式转换为整数,然后转换为Enum2的值。如果按如下方式重新定义Enum1。。。

public enum Enum1
{
    ONE = 0,
    TWO = 1,
    THREE = 2,
}

则它将

失败不返回"A,B",因为Enum2中没有整数值2的值

当您使用Enum.GetValues()时,它会返回基本值。使用foreach(Type...)时,它将强制转换为枚举类型。因此,虽然它们可能不是同一个Enum,但它们具有相同的底层值,因此不存在强制转换问题。

发生的事情大致相当于这个

int value = Enum.GetValues(typeof(Enum2))[1]; // this isn't valid code, it's more simplified
Enum1 casted = (Enum1)value;

Enum.GetValues(typeof(Enum1))返回{0,1}并且foreach将在此范围内枚举

这里有一个来自Enum1->int和int->Enum2的隐式强制转换。

我想像Jon Skeet这样的人可以来这里,比我更好地完全解释正在发生的事情,但这段代码:

foreach (Enum2 e in Enum.GetValues(typeof(Enum1)))
{
    Console.WriteLine(e);
}

将您的所有Enum1值视为Enum2类型。

由于enum数据类型与int数据类型类似,因此Enum1中的数值将用于索引Enum2

这是因为枚举可以隐式地传递到System.Int(假设它们是int枚举,默认情况下是int枚举)。

然后,您的第二个foreach显式地将Enum.GetValues(typeof(Enum1))的结果强制转换为Enum2