简体   繁体   English

C#Nullable值类型生成垃圾?

[英]C# Nullable value type generates garbage?

Does a Nullable value type generate garbage? Nullable值类型是否会生成垃圾? For example: A struct is not created on the heap but on the stack because it's a value type. 例如:结构不是在堆上创建的,而是在堆栈上创建的,因为它是一个值类型。 But when that struct is made nullable, is it still a value type and still created on the stack? 但是当该结构可以为空时,它仍然是一个值类型并仍然在堆栈上创建吗?

I ask this question because I need a nullable struct that does not generate garbage. 我问这个问题,因为我需要一个不会产生垃圾的可以为空的结构。

A struct is not created on the heap but on the stack because it's a value type. 结构不是在堆上创建的,而是在堆栈上创建的,因为它是值类型。

That is a common misperception, and completely misleading. 这是一种常见的误解,完全是误导。 A struct that is an array element is created on the heap. 在堆上创建作为数组元素的结构。 A struct that is a field of a class is created on the heap. 在堆上创建作为类的字段的结构。 A struct that is a closed-over outer variable of a lambda is created on the heap. 在堆上创建一个结构,它是lambda的一个封闭的外部变量。 Structs are created on the heap all the time. 结构始终在堆上创建。 Structs are only created on the stack when their variable lifetimes are known to be shorter than that of the method they're in. Obviously they cannot be created on the stack if their lifetimes are longer than the stack frame of the method !. 只有当已知的变量生命周期比它们所处的方法的变量生命周期短时,才会在堆栈上创建结构。显然,如果它们的生命周期比方法的堆栈框架长,它们就无法在堆栈上创建!

Also, everyone forgets registers. 此外,每个人都忘记了注册。 Registers are neither heap nor stack. 寄存器既不是堆也不是堆栈。 Nothing stops the optimizer from generating a struct as a register if the optimizer decides that burning the register is worth it. 如果优化器决定刻录寄存器是值得的,那么优化器就不会阻止优化器生成结构作为寄存器。

But when that struct is made nullable, is it still a value type? 但是当该结构可以为空时,它仍然是值类型吗?

Yes. 是。 A nullable type is a value type. 可空类型是值类型。 (Though it does not meet the value type constraint of a generic type or method, and it has special boxing behaviour.) (虽然它不符合泛型类型或方法的值类型约束,但它具有特殊的装箱行为。)

Is it still created on the stack? 它仍然是在堆栈上创建的吗?

If the non-nullable value type would have been created on the heap then the nullable one will be created there too. 如果在堆上创建了非可空值类型,那么也将在那里创建可以为空的值。

I need a nullable struct that does not generate garbage. 我需要一个不会生成垃圾的可空结构。

If the non-nullable struct did not generate garbage then the nullable struct will not either. 如果非可空结构不生成垃圾,那么可空结构也不会生成垃圾。

Looking at Nullable of T on MSDN, it's clear that nullables are still structs and so therefore are still created on the stack where appropriate. 在MSDN上查看N的Nullable ,很明显,nullables仍然是结构,因此仍然在适当的堆栈上创建。

[SerializableAttribute]
public struct Nullable<T>
where T : struct, new()

Not true that structs are created on stack only. 不仅仅是在堆栈上创建结构。

This post explains how Nullable works. 这篇文章解释了Nullable的工作原理。 Where in memory are nullable types stored? 内存中可存储的可空类型?

The short and to the point answer is, if you want them to not live in the heap, make them : 简短的答案是,如果你希望他们不住在堆中, 那就制作它们

local variables or temporaries, and the local variables are not closed-over outer variables of an anonymous method or lambda, and the local variables are not in an iterator block. 局部变量或临时值,局部变量不是匿名方法或lambda的外部变量,而局部变量不在迭代器块中。

It's pretty risky to base some part of your logic on this fact, as it's subject to change and carries no guarantees. 将这部分逻辑基于这一事实是非常危险的,因为它可能会发生变化而无法保证。 This applies to the raw value types as well, so sentinel values instead of using Nullable<T> won't suddenly remove this issue. 这也适用于原始值类型,因此Sentinel值而不是使用Nullable<T>不会突然删除此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM