According to a video from a conference session called "Writing Allocation Free Code In C#", the Net Core team is taking efforts to reduce unnecessary object allocations. Since struct
is a "Value" type, it exists on the stack and is passed by copy. That is in opposition to the class
which is a "Reference" type which exists in heap memory. There are a couple reasons to move in this direction:
- Performance as stack allocation and clean up of small objects is faster than allocating and deallocating heap objects.
- Runtime stability, not in the sense of things breaking, but more in the sense of reducing garbage collection pauses.
Some of the areas where this can make a big difference include the following:
- Mobile gaming
- Internet of Things devices (constrained runtime)
That said, it is very difficult to get the right application behavior using value types when most everything you use is a reference type. These changes are targeted with new APIs and new language features. In select cases (like List<T>.Enumerator
) the newer iterations of Net Core will be making those optimizations in areas that they have the best hope of getting right.
I'm hoping the YouTube video stays up indefinitely, since there is a lot of good information on what language features and API changes support value types better.
I will repeat the same caveat that the speaker in the video had: Don't switch to value types in your APIs unless you really need to (for performance, etc.). It is easy to do it wrong, particularly where the struct is maintaining state like an enumerator. That said, the features are there when you need to make use of them.
struct
likeValueTask<T>
when you are running a task synchronously.GetEnumerator
gets called (which includes every time you do aforeach
over theList<T>
) theEnumerator
gets instantiated. And yes, you could very easily be doing that every frame in a video game. Although, that is on aList<T>
, on an array as Andres says, theforeach
would be optimized into indexed access.