Nullable值类型是否会生成垃圾?例如:结构不是在堆上创建的,而是在堆栈上创建的,因为它是一个值类型。 但是当该结构可以为空时,它仍然是一个值类型并仍然在堆栈上创建吗?
我问这个问题,因为我需要一个不会产生垃圾的可以为空的结构。
答案 0 :(得分:20)
结构不是在堆上创建的,而是在堆栈上创建的,因为它是一个值类型。
这是一种常见的误解,完全是误导。在堆上创建作为数组元素的结构。在堆上创建作为类的字段的结构。在堆上创建一个结构,它是lambda的一个封闭的外部变量。结构始终在堆上创建。只有当已知的变量生命周期短于它们所处方法时,结构才会在堆栈上创建。显然,如果它们的生命周期比方法的堆栈框架长,则无法在堆栈上创建结构< / em>的!
此外,每个人都忘记了注册。寄存器既不是堆也不是堆栈。如果优化器决定刻录寄存器是值得的,那么优化器就不会阻止优化器生成结构作为寄存器。
但是当该结构可以为空时,它仍然是一个值类型吗?
是。可空类型是值类型。 (虽然它不符合泛型类型或方法的值类型约束,但它具有特殊的装箱行为。)
它是否仍然在堆栈上创建?
如果在堆上创建了不可为空的值类型,那么也将在那里创建可为空的值。
我需要一个不会产生垃圾的可以为空的结构。
如果非可空结构没有生成垃圾,那么可空结构也不会。
答案 1 :(得分:3)
在MSDN上查看Nullable of T,很明显,nullables仍然是结构体,因此仍然在适当的堆栈上创建。
[SerializableAttribute]
public struct Nullable<T>
where T : struct, new()
答案 2 :(得分:3)
不正确仅在堆栈上创建结构。
这篇文章解释了Nullable的工作原理。 Where in memory are nullable types stored?
答案 3 :(得分:2)
简短而重要的答案是,如果你希望他们不住在堆里,请them:
局部变量或临时变量,并且局部变量不会被关闭 匿名方法或lambda的外部变量,以及局部变量 不在迭代器块中。
将这部分逻辑基于这一事实是非常危险的,因为它可能会发生变化并且不会得到任何保证。这也适用于原始值类型,因此,而不是使用Nullable<T>
而使用的哨兵值不会突然消除此问题。