Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any run-time overhead to readonly?

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?

like image 669
JulianR Avatar asked May 27 '09 00:05

JulianR


People also ask

What is the purpose of readonly modifier?

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.

What is the purpose of readonly in C#?

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.

What is readonly?

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.

What is difference between constant and readonly in C#?

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.


1 Answers

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:

  1. Create Assembly A.dll with public class C
  2. Create an Assembly B.exe that references A.dll. B.exe uses class C.
  3. Build the two assemblies. Running B.exe works just fine.
  4. Rebuild A.dll but set class C to internal. Replace A.dll in B.exe's directory.

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.

like image 197
Szymon Rozga Avatar answered Oct 08 '22 21:10

Szymon Rozga