What\'s the difference between struct and class in .NET?
To add to the other answers, there is one fundamental difference that is worth noting, and that is how the data is stored within arrays as this can have a major effect on performance.
So an array of structs looks like this in memory
[struct][struct][struct][struct][struct][struct][struct][struct]
Whereas an array of classes looks like this
[pointer][pointer][pointer][pointer][pointer][pointer][pointer][pointer]
With an array of classes, the values you're interested in are not stored within the array, but elsewhere in memory.
For a vast majority of applications this difference doesn't really matter, however, in high performance code this will affect locality of data within memory and have a large impact on the performance of the CPU cache. Using classes when you could/should have used structs will massively increase the number of cache misses on the CPU.
The slowest thing a modern CPU does is not crunching numbers, it's fetching data from memory, and an L1 cache hit is many times faster than reading data from RAM.
Here's some code you can test. On my machine, iterating through the class array takes ~3x longer than the struct array.
private struct PerformanceStruct
{
public int i1;
public int i2;
}
private class PerformanceClass
{
public int i1;
public int i2;
}
private static void DoTest()
{
var structArray = new PerformanceStruct[100000000];
var classArray = new PerformanceClass[structArray.Length];
for (var i = 0; i < structArray.Length; i++)
{
structArray[i] = new PerformanceStruct();
classArray[i] = new PerformanceClass();
}
long total = 0;
var sw = new Stopwatch();
sw.Start();
for (var loops = 0; loops < 100; loops++)
for (var i = 0; i < structArray.Length; i++)
{
total += structArray[i].i1 + structArray[i].i2;
}
sw.Stop();
Console.WriteLine($"Struct Time: {sw.ElapsedMilliseconds}");
sw = new Stopwatch();
sw.Start();
for (var loops = 0; loops < 100; loops++)
for (var i = 0; i < classArray.Length; i++)
{
total += classArray[i].i1 + classArray[i].i2;
}
Console.WriteLine($"Class Time: {sw.ElapsedMilliseconds}");
}