首先,我认为您的困惑new
来自 C++。在那里,您可以编写类似MyEnum e = MyEnum();
或的内容MyEnum* e = new MyEnum();
,其中每个都表示不同的含义。在 C# 中没有这样的区别,无论您是否使用创建值都new
没有关系。
我读到 [...] 枚举存储在堆栈中。
那是过于简单化了,当这样说时,我会说这是错误的。Enum
s 可以存储在堆栈中,是的,但它们也可以存储在堆或寄存器中。在大多数情况下,它们的确切存储位置对您来说并不重要。
但是在上面的代码片段中,我实例化了我的 Enum 类型。这个实例是存储在堆上的吗?
就像我上面说的,你使用new
. 值的具体存储位置取决于具体情况。
如果变量实际上是一个简单的局部变量:
let a = MyEnum.A
printfn "%A" a
然后它将存储在堆栈或寄存器中。
但是你也可以使用相同的语法来定义一个类型的字段:
type Test() =
let a = MyEnum.A
member this.A
with get() = a
printfn "%A" (Test().A)
在这种情况下,Test
是一个 .Net 类,它是一个引用类型,因此a
将存储在为某些Test
对象分配的内存中的堆内。
但也有不太明显的情况。例如:
let a = MyEnum.A
let getA() = a
printfn "%A" (getA())
在这种情况下,本地a
不会存储在任何地方,因为代码getA()
将被优化为MyEnum.A
直接返回。
let a = (fun() -> MyEnum.A)()
let getA() = a
printfn "%A" (getA())
使初始化a
更复杂意味着不会使用先前的优化,a
现在存储在静态字段中(这些通常存储在堆的特殊部分中)。
因此,如您所见,该值的确切存储位置可能非常复杂且特定于编译器。而且你不应该关心它,除非你正在执行微优化。此外,它肯定与new
.
这个技巧不起作用:
typeof<MyEnum>.BaseType = typeof<System.ValueType>
...因为枚举是 System.Enum 类型
但Enum
它本身是从 派生的ValueType
,所以返回true
:
typeof<MyEnum>.BaseType.BaseType = typeof<System.ValueType>
尽管System.Enum
和System.ValueType
它们本身是引用类型这一事实使情况更加混乱。