Why would one ever use the “in” parameter modifier in C#?

  • A+
Category:Languages

So, I (think I) understand what the in parameter modifier does. But what it does appears to be quite redundant.

Usually, I'd think that the only reason to use a ref would be to modify the calling variable, which is explicitly forbidden by in. So passing by in reference seems logically equivalent to passing by value.

Is there some sort of performance advantage? It was my belief that on the back-end side of things, a ref parameter must at least copy the physical address of the variable, which should be the same size as any typical object reference.

So, then is the advantage just in larger structs, or is there some behind-the-scenes compiler optimization that makes it attractive elsewhere? If the latter, why shouldn't I make every parameter an in?

 


in was recently introduced to the C# language.

in is actually a ref readonly. Generally speaking, there is only one use case where in can be helpful: high performance apps dealing with lots of large readonly structs.

Assuming you have:

readonly struct VeryLarge {     public readonly long Value1;        public readonly long Value2;     // etc } 

and

void Process(in VeryLarge value) { } 

In that case, the VeryLarge struct will be passed by-reference without creating of defensive copies when using this struct in the method, and the struct immutability is ensured by the compiler.

Note that passing a not-readonly struct with an in modifier will cause the compiler to create a defensive copy when using that struct in the method, which will negatively affect performance!

There is a really good MSDN blog entry which I recommend to carefully read.

If you would like to get some more historical background of in-introducing, you could read this discussion in the C# language's GitHub repository.

In general, most developers agree that introducing of in could be seen as a mistake. It's a rather exotic language feature and can only be useful in high-perf edge cases.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: