We all know that mutable structs are evil. But of course the performance demands of numerical/game code sometimes top good design. Still I think that you use too much mutability here.
I see several types of struct mutability in general
Public mutable fields
Properties with public setters
Modifying structs passed in via ref/out
Methods mutating this
In my experience 4 is the one that creates the most subtle bugs. Mistakes with 1, 2 and 3 are usually prevented by the compiler. But the compiler doesn't help when you make a mistake with type 4 mutations.
The typical example is that you call such a mutating function on a temporary variable without noticing you did. For example readonly fields or properties are common traps.
I noticed that most of your code avoids type 4 mutations. But there are some methods that do use them. In particular Normalize and Conjugate.
I suggest replacing them with new methods(with a different name obviously) that return their result instead of modifying this.
If you want to keep these methods around for XNA compatibility I suggest marking them as obsolete and adding an attribute to hide them from intellisense.
We all know that mutable structs are evil. But of course the performance demands of numerical/game code sometimes top good design. Still I think that you use too much mutability here.
I see several types of struct mutability in general
ref
/out
this
In my experience 4 is the one that creates the most subtle bugs. Mistakes with 1, 2 and 3 are usually prevented by the compiler. But the compiler doesn't help when you make a mistake with type 4 mutations.
The typical example is that you call such a mutating function on a temporary variable without noticing you did. For example readonly fields or properties are common traps.
I noticed that most of your code avoids type 4 mutations. But there are some methods that do use them. In particular
Normalize
andConjugate
.I suggest replacing them with new methods(with a different name obviously) that return their result instead of modifying
this
.If you want to keep these methods around for XNA compatibility I suggest marking them as obsolete and adding an attribute to hide them from intellisense.