The `in` modifier on parameters, to specify that an argument is passed by reference but not modified by the called method.
The `ref readonly` modifier on method returns, to indicate that a method returns its value by reference but doesn't allow writes to that object.
The `readonly struct` declaration, to indicate that a struct is immutable and should be passed as an `in` parameter to its member methods.
The `ref struct` declaration, to indicate that a struct type accesses managed memory directly and must always be stack allocated.
ReadOnlySpan also gives immutability; though will only work over contiguous memory rather than a more general collection type; for which you'd still need to use a IReadOnly* interface either as param or generic constraint.
Thank you for additional clarification, I can see that some of related issues like https://github.com/dotnet/csharplang/issues/38 are not yet closed too, so it may cause additional confusion about its status.
I think that a C++'s const& equivalent would be very useful in C#, especially to simplify making objects and value types immutable by default and also more performant. I created https://github.com/dotnet/csharplang/issues/1118 as a starter point for discussion, although I'm not sure if linking it to "ref readonly" that's available for value types is the right association to make in terms of more general C# roadmap and design.
The `in` modifier on parameters, to specify that an argument is passed by reference but not modified by the called method.
The `ref readonly` modifier on method returns, to indicate that a method returns its value by reference but doesn't allow writes to that object.
The `readonly struct` declaration, to indicate that a struct is immutable and should be passed as an `in` parameter to its member methods.
The `ref struct` declaration, to indicate that a struct type accesses managed memory directly and must always be stack allocated.
ReadOnlySpan also gives immutability; though will only work over contiguous memory rather than a more general collection type; for which you'd still need to use a IReadOnly* interface either as param or generic constraint.