so, if I have for example a struct PlayerData that has members of Vector3 structs defined in System.Numerics (not readonly structs)
public readonly struct PlayerData
{
public readonly Vector3 SpawnPoint;
public readonly Vector3 CurrentPosition;
public readonly Vector3 Scale;
...constructor that initializes fields
}
and I pass them to the method:
AddPlayerData(new PlayerData(Vector3.Zero, Vector3.UnitX, Vector3.One))
public void AddPlayerData(in PlayerData playerData)
{
...
}
Will c# create defensive copy because of Vector3 members that are not readonly structs but are readonly fields? Existing libraries don't offer readonly versions of Vectors so am I forced to forget the whole in parameter optimization when passing structs that are bigger than intptr if I don't write my own versions for basic vectors? Information about usage is not that clear when reading: https://learn.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code
Interesting question. Lets test it:
Gives compiler error:
From this I would assume the compiler would not create any defensive copy, since the non-readonly struct cannot be modified anyway. There might be some edge case that allow the struct to change, I'm not well versed enough in the language specification to determine that.
It is however difficult to discuss compiler optimizations since the compiler is usually free to do whatever it wants as long as the result is the same, so the behavior might very well change between compiler versions. As usual the recommendation is to do a benchmark to compare your alternatives.
So lets do that:
For me using .Net framework 4.8 this gives
I.e. well within measurement errors. So I would not worry about it.