C# Readonly

  • The readonly keyword is a field modifier which can only be used on a field.
  • The field with readonly modifier can only be initialized once in either the declaration statement or in a constructor.
  • Once the readonly field is assigned with a value, it will not be changed any more otherwise an error message will be issued.
  • The readonly modifier can be used with static keyword to define a static readonly field which can be initialized in a static constructor.
  • Like static keyword, readonly can be defined in any sequence with static or access modifier before the type of the field.

For example:

readonly static public int a;	// Legal
public readonly static int a;	// Legal
static readonly public int a;	// Legal
static public int readonly a;	// Illegal

readonly vs const

  • A const field must be initialized in the declaration statement but a readonly field can be initialized in the declaration or a constructor.
  • readonly is more flexible than const because it can be initialized with different values based on different situations in a constructor.
  • The readonly field can be regarded as a runtime constant and a const field is regarded as a compile-time constant.

Example 01-62-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;

namespace ReadonlyKeyword
{
    public class Circle
    {
        static readonly double PI;
        public readonly string name;
        double radius;

        static Circle()
        {
            PI = 3.14;
        }

        public Circle(string name)
        {
            if (name.Equals(""))
            {
                this.name = "Empty";
            }
            else
            {
                this.name = name;
            }
        }

        public Circle(string name, double radius) : this(name)
        {
            this.radius = radius;
        }

        public double area()
        {
            return PI * radius * radius;
        }
    }

    public class TestCircle
    {
        public static void Main()
        {
            Circle a = new Circle("Circle A", 5);
            Circle b = new Circle("", 10);

            Console.WriteLine("{0}: area is {1}", a.name, a.area());
            Console.WriteLine("{0}: area is {1}", b.name, b.area());

            //b.name = "Circle B";
            Console.Read();
        }
    }
}

Output

Circle A: area is 78.5
Empty: area is 314

Explanation

  • Line 5-37: Define a public class Circle.
  • Line 7-9: Define a static readonly field PI, a readonly field name and a field radius.
  • Line 11-14: Define a static constructor to initialize the static readonly field PI.
  • Line 16-26: Define a constructor with a parameter name to initialize the readonly field name. The field "name" will be assigned with "Empty" if the parameter is transferred with an empty string.
  • Line 28-31: Define the second non-static constructor with 2 parameters. At first, this keyword is used to call the first constructor to assign "name" field's value.
  • Line 33-36: The method is defined to return the area of the circle.
  • Line 41: Start running Main() in TestCircle class.
  • Line 43-44: Instantiate class Circle twice and assign the objects to 2 instances a and b.
  • Line 46-47: Output the name and area of each object. The name of the second one is printed with "Empty".
  • Line 49: If you try to change the empty name with the correct name, you will get the following error message. So this line is commented out.
A readonly field cannot be assigned to (except in a constructor or a variable initializer)