C# Futures: Read-Only Local Variables

| by Jonathan Allen Follow 612 Followers on Apr 24, 2017. Estimated reading time: 2 minutes |

Not too long ago the proposal for read-only local variables was revived. This is a much more modest feature than the read-only references proposal, but the two are complementary.

The basic syntax for read-only local variables is to simply prepend the type name with the readonly keyword. This would work in local variables essentially in the same way it works for fields. You would also be able to apply the readonly keyword to parameters.

As a short cut, you can use let in lieu of readonly var. The keyword let was chosen for several reasons:

  • It is only a keyword in C# LINQ expressions for read-only range variables
  • It is also the keyword in F# (and other languages) for declaring read-only local variables
  • It is more visually distinct than val, another popular keyword for this role

The basic use case for this is informational; it tells the person reading the code that the local variable won’t change once set.

The proposal notes that it is also useful for defensive coding when using anonymous or asynchronous functions. A common mistake is to create a closure over a local variable, then pass that closure to a different thread. This causes a hard to detect race condition, as most developers don’t think about race conditions as even being possible for local variables. By marking the variable as read-only, the compiler will prevent reassignment in the closure.

You would not be able to pass a read-only variable to a function as a ref or out argument. You could, however, pass it as a readonly ref argument if that proposal is also implemented.

Warning: if you declare a struct variable, local or parameter as read-only, then you cannot call methods on it without the compiler implicitly making a copy. For small structs such as integers, this isn’t an issue, but it can be problematic for large structs with non-trivial copying costs. See “readonly structs” in the read-only references proposal for a possible fix.

Open Design Questions

While let x would require immediate assignment, there is an open question as to if readonly Type x would as well.

The argument for it is that requiring assignment at declaration makes it easier to see what that assignment was. Plus, it makes the overall proposal simpler.

The argument against requiring immediate assignment is likewise deals with readability. There are times when using conditional notation (x = a ? b : c) makes the code harder to read. And it wouldn’t work at all if you needed to support a try-catch block.

More Information

Rate this Article

Adoption Stage

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Of course it works with try catch blocks by Johannes Egger

let foo = Bar()

public string Bar()
return "Bar";
return "Baz";

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

1 Discuss

Login to InfoQ to interact with what matters most to you.

Recover your password...


Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.


More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.


Stay up-to-date

Set up your notifications and don't miss out on content that matters to you