🤔 CONST vs READONLY in C#? (Explanation)
Tags: dotnet, programming, beginners, csharp
Published: 2021-06-22 07:46:00

Who does not have doubts when starting to learn something new?🤔

All the world

In this case, when someone starts programming in .NET they usually get a questions that even many Senior Developers don’t know how to answer correctly:

>*What are the differences between READONLY and CONST?*

>*They are the same?*

>*If a variable that can only be read and not changed is assumed… Could the definition of constant be applied to it?*

I answer you:

NO ❌

Okay but… If they are not the same… What is their difference?

Well, let’s start with the basics:

At first, they may seem the same if we take into account that the outputs are similar, but, we must understand the real differences between them since if we do not use them well we could have many problems in our projects.

---

## 1. Read only

To define a constant in C# we will use this 👇

```csharp
public const double PI = 3.14;
```

With the const modifier we tell the compiler that the variable we are assigning will be a constant. In this way, it can only be initialized when it is declared.

If we want to modify it, the compiler will tell us no and show us this error:


![exit code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p0twtrmoardxsc0wwk7.png)

In the case of defining a read-only variable, it is similar 👇

```csharp
public readonly double PI = 3.14;
```

And again, if we try to modify it, it will give us an error again, but not the same one:


![dev](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn1nxdaarnxd8wk14tre.png)

### ✅ Conclution:

Although both of us have given us errors, it has not been the same. In this case the difference is that the readonly classes CAN be modified, only as long as the constructor of that class is not executed.

**What did I mean by that?**

Simply being inside the constructor we can modify them if we want, for example, obtaining their value from parameters that we pass to the constructor. And no, that is not possible in the case of the constant.

---

## 2. Static members

The second most notable difference is that a constant is **ALWAYS** a static member of the class to which it belongs.

Let’s go back to practice, if we write:

```csharp
public class Class01{ public const double PI = 3.14;}
```

And then we try to access the value of PI, it would not be necessary to create a new object of the class, that is 👇

```csharp
Console.Write("The Pi value is " + Class01.PI);
```

We would not need to instantiate anything at any time, since being a static member, common with the other objects of that class and clearly existing in its definition.

If we want to do the same with a read-only variable, we would have to add the static modifier. It would look like this 👇

```csharp
public class Class01{ public static readonly double PI = 3.14;}
```

So we could use it in the same way as the constant.

---

## 3. Compilation

Is everything clear at the moment? 🤗

Now we are going to “dig in” a little more.

Suppose we have a basic class defined like this:

```csharp
using System;
namespace ConstantTestLIB
{
     Public class Class01
     {
          Public static readonly double readonlyPI = 3.14;
          Public const double constantPI = 3.14;
     }
}
```

Basically, as in the first example, we define a single class with the two static members 👇

- Readonly Pi
- Const Pi

We generate a .dll so that we can use it in other applications.

Now, we create a new project and add a reference to the DLL created earlier. And we just show an output on screen like here:

```csharp
using System;
using ConstantTestLIB;
namespace ConstantTestCMD
{
     class Program
     {
          Static void Main (string[] args)
          {
          Console.WriteLine(“The constant is: ” + Class01.ConstantPI 
          + “and the readonly is: ” + Class01.ReadOnlyPI);
          }
     }
}
```

If we run this, the result will be 👇


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwy23ivs88wyfvucf8sl.png)

Okay, all right, right?

Now let’s imagine that we compile and ship our new console application to our clients.

Ohh wait, the PI value is longer…😰

Okay, we just change the DLL code, compile it and send it back to it 👍

It would simply be necessary to overwrite the new DLL with the old one and everything would work without any problem. But … Let’s run the program again with the new DLL. You gonna crash like Windows 10 blue screen👇


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9mx9ce355c4vy14uo9k.png)

Only the value of the read-only variable has been changed and not the constant.

If we examine the generated code with a decompiler, we will find this 👇


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnspdhhabssgo2asjnfr.png)


With this we can realize that, even though they are a member in a class that belongs to external *DLL*, the constants are compiled **literally.**

✅ This is **VERY** simple to explain:

When the compiler parses the code, seeing that we are using a constant and it **cannot be changed**, it simply changes it to the real value on all sides, even if we compile it with an external *DLL.*

In the case of *read-only* variables, we can see that it is still used from the *DLL.*

At this point we come to the main problem that you can find. If you declare a *read-only* variable and you want to change its value, overwriting the DLL does not work, you will have to compile all the applications that use it again.

---

Finally, I hope that with this article I have clarified the most important differences between read-only variables and constants.

Thus being able to avoid possible problems and a few more compilations, which I think we already waste a lot of time on it. 🤗