When you define a field with the readonly keyword, you have the ability to set that field's value in one place: the constructor. After that point, the field cannot be changed by either the class itself or the class's clients. Let's say you want to keep track of the screen's resolution for a graphics application. You can't address this problem with a const because the application cannot determine the end user's screen resolution until run time, so you use code like that at the top of the following page.
using System; class GraphicsPackage { public readonly int ScreenWidth; public readonly int ScreenHeight; public GraphicsPackage() { this.ScreenWidth = 1024; this.ScreenHeight = 768; } } class ReadOnlyApp { public static void Main() { GraphicsPackage graphics = new GraphicsPackage(); Console.WriteLine("Width = {0}, Height = {1}", graphics.ScreenWidth, graphics.ScreenHeight); } }
At first glance, this code seems to be just what you would need. However, there's one small issue: the read-onlyfields that we defined are instancefields, meaning that the user would have to instantiate the class to use the fields. This might not be a problem and could even be what you want in cases in which the way the class is instantiated will determine the read-onlyfield's value. But what if you want a constant, which is static by definition, that can be initialized at run time? In that case, you would define the field with both the static and the readonly modifiers. Then you'd create a special type of constructor called a static constructor. Static constructors are constructors that are used to initialize static fields, read-only or otherwise. Here I've modified the previous example to make the screen resolution fields static and read-only, and I've added a static constructor. Note the addition of the static keyword to the constructor's definition: -
using System; class GraphicsPackage { public static readonly int ScreenWidth; public static readonly int ScreenHeight; static GraphicsPackage() { // Code would be here to // calculate resolution. ScreenWidth = 1024; ScreenHeight = 768; } } class ReadOnlyApp { public static void Main() { Console.WriteLine("Width = {0}, Height = {1}", GraphicsPackage.ScreenWidth, GraphicsPackage.ScreenHeight); } }