Const and Readonly in C#
Tags: programming, coding, beginners, csharp
Published: 2023-06-20 08:52:49

Immutability is a core concept in software development, offering numerous benefits including code predictability, easier reasoning, and reduced bugs. Languages like C# support immutability through several mechanisms, two of which are the `const` and `readonly` keywords.

## Const

The `const` keyword is used to declare a constant, that is, a variable whose value cannot be changed after initialization. When declaring a constant, you must assign it a value.

```csharp
public const int MyConstant = 10;
```

In this example, `MyConstant` is a constant that has been initialized with the value `10`. From this point onwards, the value of `MyConstant` cannot be changed at any other point in the code.

## Readonly

The `readonly` keyword can be used in four contexts:

1️⃣ In a field declaration, `readonly` indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class.

```csharp
public class MyClass
{
    private readonly int _myReadonlyVariable;
    
    public MyClass() 
    {
        _myReadonlyVariable = 10;
    }
}
```

> ⚠️ **Warning**
> _An externally visible type that contains an externally visible read-only field that is a mutable reference type may be a security vulnerability and may trigger warning [CA2104](https://learn.microsoft.com/en-us/visualstudio/code-quality/ca2104?view=vs-2022&tabs=csharp) : "Do not declare read only mutable reference types."_

2️⃣ In a `readonly struct` type definition, `readonly` indicates that the structure type is immutable.

```csharp
public readonly struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; init; }
    public double Y { get; init; }

    public override string ToString() => $"({X}, {Y})";
}
```

3️⃣ In an instance member declaration within a structure type, `readonly` indicates that an instance member does not modify the state of the structure.

Typically, you apply the `readonly` to the following kinds of instance members:

- Methods:

```csharp
public readonly double Sum()
{
    return X + Y;
}
```

You can also apply the `readonly` to methods that override methods declared in `System.Object`:

```csharp
public readonly override string ToString() => $"({X}, {Y})";
```

- Properties and indexers:

```csharp
private int counter;
public int Counter
{
    readonly get => counter;
    set => counter = value;
}
```

In C# 9.0 and later, you may apply the `readonly` to a property or indexer with an `init` accessor:

```csharp
public readonly double X { get; init; }
```

4️⃣ In a `ref readonly method` return, the `readonly` indicates that method returns a reference and writes are not allowed to that reference.

```csharp
private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;
```

## Differences between `const` and `readonly`

Although `const` and `readonly` seem similar, there are some key differences between the two:

- **Initialization**: A constant must be initialized at the time of declaration, whereas a readonly variable can be initialized at the time of declaration or in a constructor.
- **Type of value**: A constant can hold only primitive or a `null` reference, whereas a readonly variable can hold any type of value.
- **Scope**: Constants may have a global scope and can be used anywhere in the code, whereas readonly variables are confined within the class they are declared in.
- **Runtime vs compile time**: Constants are evaluated at compile time, whereas readonly variables can be evaluated at runtime.

## Conclusion

Understanding the functionalities and applications of `const` and `readonly` keywords is fundamental in C# programming. Both provide you with the ability to protect your variables from unintended changes, promoting code safety and predictability.

While constants are suitable for values that will never change, readonly variables provide a little more flexibility, as they can be assigned within constructors. This distinction makes `readonly` variables a perfect choice for values that are known at the time of object construction but are not known at compile time.

Remember, the right use of these keywords not only increases code readability and maintainability but also prevents potential bugs caused by inadvertent changes to these values. Always consider your specific use case, the nature of the values your variables will hold, and where and how they will be used within your code when choosing between `const` and `readonly`.

## References

- [const (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const)
- [readonly (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/readonly)