编辑:添加了一些探索数组迭代的许多(也许全部?)可能方法的示例代码。
枚举类型默认情况下被认为是从 int 派生的。您可以选择将其派生自其他整数类型,例如 byte、short、long 等。
在两种情况下,对 Enum.GetValues 的调用都会返回一个 ReportStatus 对象数组。
在第一个循环中使用 var 关键字告诉编译器使用指定类型的数组,即 ReportStatus,来确定值变量的类型。枚举的 ToString 实现是返回枚举条目的名称,而不是它表示的整数值,这就是为什么第一个循环输出名称的原因。
在第二个循环中使用 int 变量会导致由 Enum.GetValues 返回的值从 ReportStatus 隐式转换为 int。在 int 上调用 ToString 当然会返回表示整数值的字符串。隐式转换是导致行为差异的原因。
更新:正如其他人指出的那样,Enum.GetValues 函数返回一个类型为 Array 的对象,并且因此它是 Object 类型的可枚举对象,而不是 ReportStatus 类型的可枚举对象。
无论如何,无论是迭代Array还是ReportStatus[],最终结果都是相同的:
class Program
{
enum ReportStatus
{
Assigned = 1,
Analyzed = 2,
Written = 3,
Reviewed = 4,
Finished = 5,
}
static void Main(string[] args)
{
WriteValues(Enum.GetValues(typeof(ReportStatus)));
ReportStatus[] values = new ReportStatus[] {
ReportStatus.Assigned,
ReportStatus.Analyzed,
ReportStatus.Written,
ReportStatus.Reviewed,
ReportStatus.Finished,
};
WriteValues(values);
}
static void WriteValues(Array values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
foreach (int value in values)
{
Console.WriteLine(value);
}
}
static void WriteValues(ReportStatus[] values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
foreach (int value in values)
{
Console.WriteLine(value);
}
}
}
为了增加一些额外的乐趣,我在下面添加了一些代码,演示了使用foreach循环迭代指定数组的几种不同方法,包括详细描述每种情况下发生的情况的注释。
class Program
{
enum ReportStatus
{
Assigned = 1,
Analyzed = 2,
Written = 3,
Reviewed = 4,
Finished = 5,
}
static void Main(string[] args)
{
Array values = Enum.GetValues(typeof(ReportStatus));
Console.WriteLine("Type of array: {0}", values.GetType().FullName);
Console.WriteLine("foreach (object value in values)");
foreach (object value in values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (ReportStatus value in values)");
foreach (ReportStatus value in values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (int value in values)");
foreach (int value in values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (object value in (ReportStatus[])values)");
foreach (object value in (ReportStatus[])values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (ReportStatus value in (ReportStatus[])values)");
foreach (ReportStatus value in (ReportStatus[])values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (int value in (ReportStatus[])values)");
foreach (int value in (ReportStatus[])values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (var value in values)");
foreach (var value in values)
{
Console.WriteLine(value);
}
Console.WriteLine("foreach (var value in (ReportStatus[])values)");
foreach (var value in (ReportStatus[])values)
{
Console.WriteLine(value);
}
}
}
-- 在上面的示例中更新了我的注释;在仔细检查后,我发现 System.Array.GetValue 方法实际上使用 TypedReference 类来提取数组元素并将其作为 System.Object 返回。我最初写道那里发生了装箱操作,但从技术上讲并非如此。我不确定装箱操作与调用 TypedReference.InternalToObject 的比较是什么;我认为这取决于 CLR 实现。无论如何,我相信现在的细节或多或少是正确的。
System.Object
,这可能在某种程度上解释了差异。 - ChrisFConsole.WriteLine()
执行其.ToString()
方法时,枚举值将返回其名称,例如“Assigned”(而不是其作为字符串的序数值,如“1”)。 - JMD