Code inspection: Possibly impure struct method is called on readonly variable: struct value always copied before invocation
Consider the following code:
We end up getting 0
in the output, while it might seem that calling IncrementValue()
beforehand should make it 1
. This happens because when we access a readonly
field of a value type, a copy of it is created to prevent the caller from mutating the field.
_readonlyStruct.IncrementValue()
in the above example creates a copy of _readonlyStruct
, changes its Value
field to 1
, and then the copy is discarded.
However, we only have this kind of problem with impure methods — methods that change the object state, like IncrementValue()
above does. Calling a pure method in a similar situation is not a problem because whether it is called on a copy or not, it doesn't change its state, and we'll get the expected result from the method anyway.
False positives
Unfortunately, ReSharper is not always able to determine whether the method is pure or not, and therefore this inspection sometimes produces false positive warnings, but methods decorated with [Pure]
(you can use both JetBrains.Annotations.PureAttribute and System.Diagnostics.Contracts.PureAttribute) are always considered pure and produce no warnings.
Note that a lot of methods in .NET Framework and other frequently used libraries are annotated with [Pure]
via external annotations.
Fixing the problem
ReSharper does not offer any quick-fixes for this inspection.
If changing the state of the field is intended in your code, you can make the field mutable by removing the readonly
modifier from it.
If you want to keep the field immutable, you should rewrite your code so that an impure method is not invoked on the field.
If the invoked method is pure and the warning is a false positive, then you can either annotate it with [Pure]
or suppress this inspection.