C
C#4w ago
Odex

`readonly` struct, `in` modifier and defensive copies

Hi people, I just encountered the in modifier for structs. As far as I'm concerned the in modifier can negatively affect performance if the struct I'm passing is NOT readonly, because it might create defensive copies - however, how can I avoid defensive copies without marking my struct readonly? Is there a rule of thumb when defensive copies are created? Thanks in advance!
11 Replies
Odex
OdexOP4w ago
As far as I know the compiler will create defensive copies whenver I'm trying to access mutable data What if I have private fields and use readonly getter for that? Will the compiler still create defensive copies?
Anton
Anton4w ago
this is not true it will create defensive copies when you try to mutate the struct by calling a non-readonly method that's it so mark all methods that don't mutate the struct as readonly
Odex
OdexOP4w ago
what about fields?
Anton
Anton4w ago
not fields, just methods and get set properties, because those are methods you won't be able to set fields and reading them can't mutate the struct
Odex
OdexOP4w ago
OH! Now everything's clear So it's safe to access fields when passing a struct with in modifier, since I can't change them (and reading won't mutate) And it's also safe to access methods as long as they are readonly
Anton
Anton4w ago
yes the whole struct doesn't have to be readonly either
Odex
OdexOP4w ago
Thanks dude! I couldn't find an exact explanation online 👍
Anton
Anton4w ago
you're welcome
Odex
OdexOP3w ago
@Anton Does this apply to only getters as well? Because the Length property of arrays it not readonly, so I'm concerned that doing something like this
public void Foo(in Bar[] bar)
{
int count = bar.Length; // defensive copy?
}
public void Foo(in Bar[] bar)
{
int count = bar.Length; // defensive copy?
}
will slow down performance
No description
Odex
OdexOP3w ago
On second thought, I don't need the in modifier at all for arrays of structs, since they're still passed by reference because arrays are allocated in the heap, right? So do you recommend me removing the in modifier when passing arrays (even if it's an array of struct)? Again, my priority is performance and avoid as many useless copies as possible
Anton
Anton3w ago
arrays are references already use ReadOnlySpan or ReadOnlyMemory for arrays (depending on whether you need to use yield return or await) autogetters are readonly iirc automatically regular getters that have code need to be specified as readonly manually for arrays there's no copy because it's a reference type in your code you're passing an immutable reference to a reference to your array as a parameter that's just a pointless level of indirection when you index the array, assign the result to a ref variable to avoid a copy

Did you find this page helpful?