`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
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
get
ter for that? Will the compiler still create defensive copies?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
what about fields?
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
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
yes
the whole struct doesn't have to be readonly either
Thanks dude! I couldn't find an exact explanation online 👍
you're welcome
@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
will slow down performance
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 possiblearrays 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