Does a Nullable value type generate garbage? 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 tha开发者_JAVA百科t 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. 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.
[SerializableAttribute]
public struct Nullable<T>
where T : struct, new()
Not true that structs are created on stack only.
This post explains how Nullable works. 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.
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.
精彩评论