将只读结构作为 "in" 参数传递?

Passing a readonly struct as an "in" parameter?

根据所有已知的 in 参数修饰符法则,任何传递的对象都将通过引用传递,但不能被调用的方法修改。

所以我发现微软在 How to write safe and efficient C# code 上的这个建议令人困惑:

Declare a readonly struct to express that a type is immutable. That enables the compiler to save defensive copies when using in parameters.

Never pass a struct as an in parameter unless it's declared with the readonly modifier or the method calls only readonly members of the struct. Violating this guidance may negatively affect performance and could lead to an obscure behavior.

如果方法无论如何都不允许修改它,为什么编译器在使用“in”参数时会保存一个防御性副本?

如果不允许方法修改非只读结构作为 in 参数传递,如何会对性能产生负面影响并导致模糊行为?

例如:

public struct Test
{
    public int Value;
    public void SetValue(int value) => Value = value;
}
public static void Method(in Test test)
{
     test.SetValue(5);
     Console.WriteLine(test.Value); // 0
 }

这会编译得很好。如果我正确理解了这种情况,则不会在调用构造函数时创建副本,而是在调用任何可能改变值的方法时创建副本。

将结构设为只读将阻止调用任何变异方法,因此将避免隐藏副本。

还有 good arguments for why mutable structs are evil,所以我主张只将所有结构设置为只读。即

public readonly struct Test
{
    public int Value { get; }
    public Test(int v) => Value = v;
    // Any "mutating" method should create a copy instead
    public Test WithValue(int v) => new Test(v); 
}