c# – Enum.GetValues()的内部工作
在阅读某人的源代码时,我遇到了一个C#片段,其行为让我感到困惑.在我开始询问之前,这是一个改编的例子:
枚举: private enum Seasons { Spring,Summer,Autumn,Winter } 用法: foreach(Seasons value in Enum.GetValues(typeof(Seasons))) { Console.WriteLine(String.Format("{0} {1}",value,(int) value)); } 输出如下所示: Spring 0 Summer 1 Autumn 2 Winter 3 我的问题: 这在C#中如何工作?来自的返回值: Enum.GetValues(typeof(Seasons)) 是一个填充值0-3的int数组. 我认为由于枚举是一个引用类型,在String.Format() – 参数“value”上,将调用ToString()方法,该方法将返回其名称.但是当转换为int时,它将在“named”值上使用Property并返回int值. 如果有人能告诉我窗帘背后是如何工作的,我会很高兴的.我查看了文档,但还是无法解决. 谢谢… 谢谢大家的答案! 但是……我真的很感激,如果有人可以再说一些关于C#内部的话.在Java中,枚举将是一个真正的引用类型,并且在内存中,它将被视为指向存储整数的另一个内存平衡的引用.非常非常简化. --------- ----------------- | | Reference |int Spring | |Seasons|-------------> |int Summer | | | |int Autumn | --------- |int Winter | ----------------- 在我看来,在C#编译器中,将它转换为类似公共const的东西(在我的例子中是一个int).请不要扔石头…… 解决方法
类型为季的变量可以在基础类型的范围内分配任何值(整数
在这种情况下).值甚至不限于枚举的命名常量.因此,通过将整数值5转换为Seasons类型来实例化Seasons值是完全合法的: Seasons season = (Seasons)5; 更新:首先要注意的事项 – System.Enum是一个值类型(它继承自ValueType),如DateTime,Int32或Boolean.如果您将查看为枚举枚举定义生成的IL,您会看到 .class public auto ansi sealed Seasons extends [mscorlib]System.Enum { .field public static literal valuetype Foo.Seasons Autumn = int32(2) .field public static literal valuetype Foo.Seasons Spring = int32(0) .field public static literal valuetype Foo.Seasons Summer = int32(1) .field public specialname rtspecialname int32 value__ .field public static literal valuetype Foo.Seasons Winter = int32(3) } 因此,这是一组公共静态字段,标记为文字 – 这使得编译器将枚举值直接嵌入到代码中.例如.以下代码 Seasons season = Seasons.Autumn; Console.WriteLine(season); 编译后,只有enum秋季成员的价值: .locals init ( [0] valuetype Foo.Seasons seasons) // it's value type! L_0000: nop L_0001: ldc.i4.2 // here simple integer value 2 is loaded L_0002: stloc.0 L_0003: ldloc.0 L_0004: box Foo.Seasons L_0009: call void [mscorlib]System.Console::WriteLine(object) 因此,实际上您具有分配给枚举类型变量的基础类型的值.没有名称或值的特殊属性.只是(任意)整数常量. 现在关于获取枚举的所有值 – 当你调用Enum.GetValues时,它返回私有Hashtable fieldInfoHash中的值,你可以在Enum类中找到它们. Hashtable缓存枚举的名称和值.因此,当您第一次获得枚举值时,会创建具有值(ulong数组)和枚举类型名称(字符串数组)的HashEntry.实际上,如果您将调用其他Enum方法(如GetNames或IdDefined),则将使用此缓存. 缓存了枚举类型的条目后,将返回值数组.但有一个技巧.这不是ulong值的简单数组.使用Enum.ToObject调用将每个值装箱为枚举类型(您可以在System.RuntimeType中找到实现): ulong[] values = Enum.InternalGetValues(this); Array array = Array.UnsafeCreateInstance(this,values.Length); for (int i = 0; i < values.Length; i++) { object obj2 = Enum.ToObject(this,values[i]); array.SetValue(obj2,i); } return array; 这就是为什么每个值对象都是Seasons类型而不是ulong类型. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |