代码检查:可能对只读变量调用了非纯结构体方法:结构体值在调用前总是被复制
请看以下代码:
class Test
{
struct MyStruct
{
public int Value;
public void IncrementValue()
{
Value +=1;
}
}
readonly MyStruct _readonlyStruct = new MyStruct();
public void RunTest()
{
// Warning: Impure method is called for readonly field of value type
_readonlyStruct.IncrementValue();
Console.WriteLine(_readonlyStruct.Value); // 0
}
}
我们最终在输出中得到 0 ,而在此之前调用 IncrementValue() 似乎应该使其变为 1。 这是因为当我们访问值类型的 只读 字段时,会创建其副本以防止调用者修改该字段。
上述示例中的 _readonlyStruct.IncrementValue() 会创建 _readonlyStruct 的副本,将其 值 字段更改为 1 ,然后丢弃该副本。
然而,我们仅在 非纯方法(例如上述的 IncrementValue() )中才会遇到此类问题——这些方法会更改对象状态。 在类似情况下调用 纯方法则不会有问题,因为无论它是否在副本上调用,都不会更改其状态,并且我们仍然会从方法中获得预期的结果。
误报
遗憾的是,JetBrains Rider 并不总是能够确定方法是否为纯方法,因此此检查有时会产生误报警告,但使用 [Pure] 装饰的方法(您可以同时使用 JetBrains.Annotations.PureAttribute和 System.Diagnostics.Contracts.PureAttribute )始终被视为 纯方法,并且不会产生警告。
请注意,.NET Framework 和其他常用库中的许多方法通过 外部注解被 [Pure] 注解。
解决问题
JetBrains Rider 不为此检查提供任何 快速修复。
如果您的代码中需要更改字段的状态,您可以通过移除 只读 修饰符使字段变为可变。
如果您希望字段保持不可变,您应重写代码以避免在字段上调用非纯方法。
最后修改日期: 2025年 9月 26日