created on 2018-04-08
Struct vs. Class in .NET
Lately, I've made a very important mistake while using structs in our persistency system(save/load game). So I wanted to write this post, which may help others, especially Unity developers. Since they mostly use C# in their programs.
So what is the difference between a struct and a class? Everybody should and probably do know by heart that, struct is a value type and class is a reference type in C#. The things is most people do not know what this means and what are the effects. I am going to give some examples to explain these effects.
- The new keyword. You can create a struct without using the new keyword, but then you need to assign all of the fields manually
- struct MyStruct
- {
- public int a;
- }
- MyStruct myStruct;
- myStruct.a = 1; // Don't do this and you are going to get a compile error
If you use the new keyword, then the fields will be assigned to their default values. (e.g. 0 for int)
- Extension methods for structs won't modify the actual object
- public static void UpdateA(this MyStruct ms)
- {
- ms.a += 1; // The passed ms object's field 'a' is still 1, remember pass by value
- }
- Still a result of being a value type, you should be careful with recursion
- public static MyStruct RecursiveA(MyStruct ms)
- {
- ms.a += 1;
- if (ms.a < 10)
- {
- RecursiveA(ms);
- }
- return ms;
- }
- ms = RecursiveA(ms);
The function above will still terminate when ms.a is 10 but the value of the actual ms.a will be 1. You can solve this problem by using a class of course or you can assign ms inside the function like this.
- public static MyStruct RecursiveA(MyStruct ms)
- {
- ms.a += 1;
- if (ms.a < 10)
- {
- ms = RecursiveA(ms);
- }
- return ms;
- }
- If you use the ref keyword, the struct will be passed by reference(its location in memory)
- public static MyStruct RecursiveA(ref MyStruct ms)
- {
- ms.a += 1;
- if (ms.a < 10)
- {
- RecursiveA(ref ms);
- }
- return ms;
- }
- // When this terminates the value of ms.a will be 10
- RecursiveA(ref ms);
Conclusion
I think it is clear that a mutable struct is not a good idea. They are good for storing read-only data. Whenever you need mutable data, you should use a class instead of a struct.
If you think that this blog post is wrong or missing, please send me a message.