I've read When should I use a struct instead of a class? which references MSDN's guidance, which says:
Do not define a structure unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (integer, double, and so on).
- It has an instance size smaller than 16 bytes.
- It is immutable.
- It will not have to be boxed frequently.
and Why are mutable structs “evil”? has answer:
Structs are value types which means they are copied when they are passed around.
I'm struggling to understand why I shouldn't just be conscious that structs need to be passed by reference, else changes made to the version passed through a function will not affect the original. Yes, I've had tons of bugs from this in the past, but now I'm experienced enough that I'm careful not to have it happen.
I make exclusively games in C#, and variables for stuff in games need to change a lot.
Say I have a player character, represented by class "Player" in my game. If Player has variables X and Y to say where it is, these would change a lot. I wouldn't want to create a new Player every time it moves, just to preserve immutability? So my class should be mutable. OK.
But what if I want to store data about my entity. If I store its position on the screen in a Rectangle (x,y,w,h), should I make Rectangle a CLASS because it's going to be mutable? It's just a logical collection of 4 variables, so a struct seems sensible as a container to me.
I also have "Colour" as a struct (r,g,b,a), but I have it as mutable because I might want to shift the alpha of things in the game to fade them in/out, or colour something red for a second when it gets hurt, without the overhead of calling "new Colour" every render call.
I saw another post which said structs should be used if these conditions are met:
- Is the main responsibility of the type data storage?
- Is its public interface defined entirely by properties that access or modify its data members?
- Are you sure your type will never have subclasses?
- Are you sure your type will never be treated polymorphically?
The answer to this would be "yes" for the structs I use, but most of them would be mutable.
I'm confused about all of the conflicting advice here. Are mutable structs OK for certain types of use, or am I designing my code all wrong?