Firld
Firld

Reputation: 37

Passing a readonly struct as an "in" parameter?

According to all known laws of the in parameter modifier, any object passed will be passed by reference BUT be unable to be modified by the called method.

So I find this advice by Microsoft on How to write safe and efficient C# code confusing:

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.

Why would the compiler save a defensive copy when using an "in" parameter if the method isn't allowed to modify it, anyway?

How can passing a non-readonly struct as an in parameter negatively affect performance and lead to an obscure behavior if the method isn't allowed to modify it?

Upvotes: 2

Views: 1917

Answers (1)

JonasH
JonasH

Reputation: 36596

For example:

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
 }

This will compile just fine. If I understand the case correctly the copy will not be created when the constructor is called, but when any methods that may mutate the value are called.

Making the struct readonly will prevent any mutating methods from being called, so hidden copies will be avoided.

There are also good arguments for why mutable structs are evil, so I would advocate just making all structs readonly. I.e.

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); 
}

Upvotes: 3

Related Questions