For some reason, I've always assumed that readonly
fields have overhead associated with them, which I thought of as the CLR keeping track of whether or not a readonly
field has been initialized or not. The overhead here would be some extra memory usage to keep track of the state and a check when assigning a value.
Perhaps I assumed this because I didn't know a readonly
field could only be initialized inside a constructor or within the field declaration itself and without a run-time check, you wouldn't be able to guarantee it's not being assigned to multiple times in various methods. But now I know this, it could easily be statically checked by the C# compiler, right? So is that the case?
Another reason is that I've read that the usage of readonly
has a 'slight' performance impact, but they never went into this claim and I can't find information on this subject, hence my question. I don't know what other performance impact there might be aside from run-time checks.
A third reason is that I saw that readonly
is preserved in the compiled IL as initonly
, so what is the reason for this information to be in the IL if readonly
is nothing more than a guarantee by the C# compiler that the field is never assigned to outside of a constructor or declaration?
On the other hand, I've found out you can set the value of a readonly int
through reflection without the CLR throwing an exception, which shouldn't be possible if readonly
was a run-time check.
So my guess is: the 'readonlyness' is only a compile time feature, can anyone confirm/deny this? And if it is, what is the reason for this information to be included in the IL?
The readonly modifier prevents the field from being replaced by a different instance of the reference type. However, the modifier doesn't prevent the instance data of the field from being modified through the read-only field.
The readonly keyword can be used to define a variable or an object as readable only. This means that the variable or object can be assigned a value at the class scope or in a constructor only. You cannot change the value or reassign a value to a readonly variable or object in any other method except the constructor.
Read-only is a file attribute which only allows a user to view a file, restricting any writing to the file. Setting a file to “read-only” will still allow that file to be opened and read; however, changes such as deletions, overwrites, edits or name changes cannot be made.
The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.
You have to look at it from the same point of view as the access modifiers. The access modifiers exist in IL, but are they really a run-time check? (1) I can't directly assign private fields at compile-time, (2) I can assign them using reflection. So far it seems no run-time check, like readonly.
But let's examine access modifiers. Do the following:
Now, running B.exe throws a runtime exception.
Access modifiers exist in IL as well, right? So what's their purpose? The purpose is that other assemblies that reference a .Net assembly need to know what they are allowed to access and what they are not allowed to access, both compile-time AND run-time.
Readonly seems to have a similar purpose in IL. It tells other assemblies whether they can write to a field on a particular type. However, readonly does not seem to have that same run-time check that access modifiers exhibit in my sample above. It seems that readonly is a compile-time check and does not occur in run-time. Take a look at a sample of performance here: Read-only performance vs const.
Again, this doesn't mean the IL is useless. The IL makes sure that a compile-time error occurs in the first place. Remember, when you build you don't build against code, but assemblies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With