Readonly structs, ref readonly and conditional ref expressions – C# 7.2 in Rider and ReSharper

Today, we continue our blog series about C# 7.2 language support in ReSharper and Rider.

In this series:

Last time we indicated that there is a remaining pitfall with in parameters. Let’s see why!

Readonly structs

There is one downside to using in parameters: for regular structs, they impose the compiler to generate copies whenever we call an instance member on it. But why do we need a copy? Didn’t we learn that in parameters will only allow us to read from that variable, and not to modify it? This is only partially true, because it only prohibits reassignments of the parameter. Instance methods of the struct are still allowed to mutate the reference by setting the this parameter – in other words, changing themselves – or reassigning fields or properties. So in order to guarantee our expectations on the call-site – that in parameters will not allow modifications – copies are being created:

The concept of readonly structs introduced with C# 7.2 can solve this issue. Adding the readonly modifier will ensure that all instance members as well as the value itself (this reference) will be completely immutable. We can’t change anything, neither from outside nor from inside the struct:

Making a struct read-only of course requires us to implement all instance members as read-only. This can easily be achieved by using the corresponding quick-fix. Instance fields will get the readonly modifier, while auto-properties will have their setter removed:
Making all members read-only

Ref readonly returns and locals

Similar to in parameters, we can make use of ref readonly returns and locals to enforce immutability and non-copying behavior on call-site: Values returned from a ref readonly member cannot be reassigned. And just like with in parameters, copies will still be created when calling instance members on non-readonly structs:

Note that when initializing a simple variable (not ref readonly) from a ref readonly member invocation, the returned value is also simply copied.

Conditional ref expressions

Sometimes we may need to get a reference to a value based on a certain condition. Prior to C# 7.2 this has been quite cumbersome, and we had to use if-else statements:

A common workaround has been to use a Choice method, passing the condition along with the consequence and alternative. However, this implied the potential danger that both the consequence and the alternative will actually be evaluated, resulting in potential errors:

So overall, conditional ref expressions can help us to declare, pass and modify values by-reference much easier.

We hope that you’ve enjoyed this blog series and that your code bases gain a lot of profit from the new C# 7.2 language features.

Download ReSharper 2018.1 now! Or give Rider 2018.1 a try. We’d love to hear your feedback!

About Matthias Koch

Matthias is a passionate C# developer and likes to talk about clean code, testing and tooling in general. Much of his spare time in the last years was devoted to his very own open source projects, including NUKE. He is working at JetBrains as developer advocate for the .NET department. Follow him on Twitter.
This entry was posted in How-To's and tagged , , , . Bookmark the permalink.

3 Responses to Readonly structs, ref readonly and conditional ref expressions – C# 7.2 in Rider and ReSharper

  1. Ulrich says:

    Readonly structs FTW! Thanks for this informative post.

  2. Hypeartist Hypeartist says:

    You are a little bit late, guys. C# 7.3 is already shipped. Any plans on support?

Leave a Reply

Your email address will not be published. Required fields are marked *