Why Does C# Disallow Readonly Local Variables

Why does C# disallow readonly local variables?

One reason is there is no CLR support for a readonly local. Readonly is translated into the CLR/CLI initonly opcode. This flag can only be applied to fields and has no meaning for a local. In fact, applying it to a local will likely produce unverifiable code.

This doesn't mean that C# couldn't do this. But it would give two different meanings to the same language construct. The version for locals would have no CLR equivalent mapping.

How to indicate that a local variable in C# will not change?

As far as I know, there is no such feature. There is the readonly keyword, but this is for class fields, not local variables.

The only solution I can come up with is to create a wrapper class, which initializes a get-only property. For ease of use, you can add implicit cast operators to and from the underlying type. But there is definitely some performance overhead to this, and it's probably not worth it.

Interestingly enough, there seems to be a question already discussing why there is no such feature.

How to make a variable (not class member) read only in C#

There isn't an identical analogue.

The readonly keyword allows the variable value to be mutated, but only in a constructor.

The const keyword means the value cannot mutate and needs to be a compile time constant and can only be one of the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type. (C# 4.0 spec §10.4).

And in c#, readonly only applies to fields and cannot be applied to local variables.

Readonly local variable cannot be used as an assignment target

The iteration variable in a foreach (i.e. myObject) cannot be assigned a new value inside the foreach. It is not allowed.

In the first scenario, the out tries to do this. In the second scenario, you *never try to reassign to myObject, so it is fine.

To quote from the ECMA specification, 15.8.4, emphasis mine:

  1. The type and identifier of a foreach statement declare the
    iteration variable of the statement.

  2. The iteration variable corresponds to a read-only local
    variable
    with a scope that extends over the embedded statement.

  3. During execution of a foreach statement, the iteration variable
    represents the collection element for which an iteration is
    currently being performed.

  4. A compile-time error occurs if the embedded statement attempts
    to modify the iteration variable (via assignment or the ++ and
    --operators) or pass the iteration variable as a ref or out parameter.

Immutable local 'variables' in C#

readonly

When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.

There's no equivalent for local variables. You'll have to make it a field.

Can define thread safe object as Readonly variable?

99.99% of the time use readonly

Traditionally you would want a readonly object as your lock, the reason being is that the lock is being done on the object at the variable lockObject if you don't make it readonly and it changes there could be a case where the lock is being placed on a different object for multiple threads.

Heres a nice list explanation of a senario that could cause issues without using a readonly lock

  1. Thread A grabs lock at lockObject
  2. Thread B changes variable at lockObject
  3. Thread C grabs lock at lockObject, which is different than the lock in step 1

For the 0.01% of the time

This would be when you want to change your lock for some reason, i.e. the resource that you are controlling access to changed but there are possibly still threads working on the previous resource and you consider their current operations still valid for your program, and you don't want to wait for them to change the lock out. Again this comes with the warning, you probably should not do this.



Related Topics



Leave a reply



Submit