为什么使用 "var" 时,Enum.GetValues() 返回名称?

12 浏览
0 Comments

为什么使用 "var" 时,Enum.GetValues() 返回名称?

有人可以解释一下这个吗?

alt text http://www.deviantsart.com/upload/g4knqc.png

using System;
namespace TestEnum2342394834
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用"var"关键字
            foreach (var value in Enum.GetValues(typeof(ReportStatus)))
            {
                Console.WriteLine(value);
            }
            //使用"int"关键字
            foreach (int value in Enum.GetValues(typeof(ReportStatus)))
            {
                Console.WriteLine(value);
            }
        }
    }
    public enum ReportStatus
    {
        Assigned = 1,
        Analyzed = 2,
        Written = 3,
        Reviewed = 4,
        Finished = 5
    }
}

0
0 Comments

Enum.GetValues()返回名称而不是值的原因是因为在代码中使用了object.ToString()方法。这个方法会返回对象的名称。

解决方法是将object类型的变量转换为enumType类型的变量,并使用ToString()方法获取其值。

这段代码的反汇编结果显示了Enum.GetValues()方法的实现。该方法首先检查传入的enumType参数是否为空,如果为空则抛出异常。然后,它检查enumType是否是RuntimeType的实例,如果不是则抛出异常。接下来,它检查enumType是否是枚举类型,如果不是则抛出异常。然后,它获取了enumType的哈希值,并使用这个哈希值创建了一个数组。接着,它使用ToObject()方法将哈希值转换为enumType类型的对象,并将其存储在数组中。最后,它返回这个数组。

根据代码的反汇编结果,我们可以看到Enum.GetValues()方法返回的是一个包含枚举类型的名称的数组。

Enum.GetValues()返回名称而不是值的原因是因为在代码中使用了object.ToString()方法。要解决这个问题,可以将object类型的变量转换为enumType类型的变量,并使用ToString()方法获取其值。

0
0 Comments

问题:为什么使用"var"时,Enum.GetValues()返回的是名称?

原因:在Enum.GetValues()方法中,返回的数组被声明为Array类型。该数组包含实际的值作为ReportStatus类型的值。因此,var关键字被解析为object类型,并且value变量保存了(装箱的)强类型枚举值。当调用Console.WriteLine时,会解析为接受object类型参数的重载方法,并在对象上调用ToString()方法。对于枚举类型,ToString()方法返回名称。

解决方法:如果想要在循环中输出枚举值而不是名称,可以将value变量的类型更改为int。由于编译器会将int隐式转换为枚举类型,所以value变量将保存常规的(非装箱的)int值。这样,Console.WriteLine调用会解析为接受int类型参数的重载方法,并将其打印出来。

文章如下:

Enum.GetValues()方法被声明为返回Array类型。该方法返回的数组包含实际的枚举值,作为ReportStatus类型的值。因此,使用var关键字时,var会被解析为object类型,并且value变量会保存(装箱的)强类型枚举值。当调用Console.WriteLine方法时,会选择接受object类型参数的重载方法,并在对象上调用ToString()方法。对于枚举类型,ToString()方法返回枚举名称。

如果想要在循环中输出枚举值而不是名称,可以将value变量的类型更改为int。编译器会将枚举类型隐式转换为int类型,因此value变量将保存常规的(非装箱的)int值。这样,Console.WriteLine调用会选择接受int类型参数的重载方法,并将其打印出来。

如果将int更改为DateTime(或其他类型),虽然代码仍然可以编译,但在运行时会抛出InvalidCastException异常。

因此,Enum.GetValues()方法返回的IEnumerable依赖于隐式转换。

注意,如果枚举的基础类型是其他数值类型(例如uintshort),第二个循环也会失败。

在第一个循环中,没有进行任何转换操作,而在第二个循环中,只允许继承转换。也就是说,既没有隐式转换,也没有显式定义的转换。

0
0 Comments

为什么在使用"var"时,Enum.GetValues()返回名称?

根据MSDN文档,Console.WriteLine的重载方法会在其参数上调用ToString方法。当你使用foreach (var value in ...)时,value变量的类型是object(因为Enum.GetValues返回一个不带类型的Array),所以Console.WriteLine调用的是object.ToString方法,而该方法被System.Enum.ToString方法重写。这个重写的方法返回enum的名称。

当你使用foreach (int value in ...)时,你将enum的值转换为int值(而不是object),因此Console.WriteLine调用的是System.Int32.ToString方法。

是的,foreach(ReportStatus会编译并打印名称。

问题出现的原因是,当使用var时,变量的类型被推断为object,而不是具体的枚举类型。因此,调用Console.WriteLine时会调用object.ToString方法,返回枚举的名称。

解决方法是将foreach循环中的变量类型显式指定为具体的枚举类型,例如foreach (ReportStatus value in ...)。这样,Console.WriteLine将调用enum类型的ToString方法,返回具体的枚举值。

总结起来,当使用var时,Enum.GetValues()返回的是不带类型的Array,变量的类型被推断为object,调用Console.WriteLine时返回枚举的名称。要解决这个问题,需要将变量类型显式指定为具体的枚举类型。

0