HomeSearch

C# readonly Keyword (Field Cannot Be Assigned To)

Use the readonly keyword. Readonly prevents changes to fields after initialization.
Readonly. This keyword prevents a field from being changed. Readonly fields can be initialized at runtime, unlike const values. Attempts to change them later are disallowed.const
This C# modifier does not affect performance. It just enforces certain constraints in the compiler. This leads to greater program quality.
An example. Here we use the readonly keyword to initialize a DateTime struct. We cannot set a const DateTime—this raises a compilation error.

Important: In this example, we want to designate a DateTime field as unavailable for further changes.

Manager: In the constructor, the startup time is initialized. We can assign the readonly field here.

ConstructorDateTime.Now

Tip: The benefit here is that other code, or the code from team members, can't change the readonly field.

And: This makes it less likely to be messed up by someone who doesn't understand its purpose.

C# program that uses readonly using System; class Program { static void Main() { Manager manager = new Manager(); Console.WriteLine(manager.GetStartup()); } } class Manager { readonly DateTime _startup; // <-- the readonly field public Manager() { // Initialize startup time. this._startup = DateTime.Now; } public DateTime GetStartup() { // We cannot modify the DateTime here. return this._startup; } } Output (Current time)
Inline initialization. It is possible to use an inline initialization for readonly. In IL Disassembler we see the compiler has put it in the constructor itself.IL Disassembler
Compiler-generated code: C# class Manager { readonly DateTime _startup = DateTime.Now; public DateTime GetStartup() { return this._startup; } }
Const. Often it is better to use constants instead. If you have a value that was established outside of your program (such as by science or research) use const.

Also: If your value is constant and you are in complete control of the program, const is better.

DLLs. When you use const, the C# compiler embeds the const variable's value directly in the IL code. Therefore, it essentially erases the const as a separate entity.

Caution: If programs that depend on a const are not recompiled after the const value changes, they may break.

DllImport, Dllexport
Benchmark. Consider this simple benchmark of readonly and const ints. The readonly int and the int field had equivalent performance. The const int was faster.

Important: Const may be faster, but the performance gain may not be worth the additional problems with maintenance of the program.

Benchmark
Class tested: C# class Test { readonly int _value1; // 1. readonly int int _value2 = 1; // 2. int const int _value3 = 1; // 3. constant int public Test() { _value1 = int.Parse("1"); } public int GetValue1() { return _value1; } public int GetValue2() { return _value2; } public int GetValue3() { return _value3; } } Code tested in loops: C# Test test = new Test(); // Outside of loops if (test.GetValue1() != 1) // 1 { throw new Exception(); } if (test.GetValue2() != 1) // 2 { throw new Exception(); } if (test.GetValue3() != 1) // 3 { throw new Exception(); } Output readonly int: 637 ms int: 635 ms const int: 317 ms [fastest]
Error. One mistake you might make when using readonly is trying to assign to it in a place that is not a constructor. This will result in the following ugly error when you try to compile.

Error: A readonly field cannot be assigned to (except in a constructor or a variable initializer).

C# program that causes error class Program { static readonly int _code = 100; static void Main() { _code = 200; } } Output Error CS0198 A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)
Public static readonly. Public static readonly fields are recommended. They are used for types that cannot be represented as const values, but are not subject to change during execution.

Note: The C# specification recommends public static readonly fields when we cannot use a const field or when the field may change.

Tip: Readonly fields are as fast as other fields. But const values are faster—they are inserted directly into the locations where used.

Tip 2: Add the System.Drawing assembly reference to compile this program. This can be done though Visual Studio's menus.

C# program that uses public static readonly fields using System; using System.Drawing; static class Points { // // Defines four public static readonly fields on a static class. // public static readonly Point TopLeft = new Point(0, 0); public static readonly Point TopRight = new Point(1, 0); public static readonly Point BottomRight = new Point(1, 1); public static readonly Point BottomLeft = new Point(0, 1); // public const Point TopLeft = new Point(0, 0); } class Program { static void Main() { // // Uses the public static readonly fields. // Console.WriteLine(Points.TopLeft); Console.WriteLine(Points.TopRight); Console.WriteLine(Points.BottomRight); Console.WriteLine(Points.BottomLeft); // Points.TopLeft = new System.Drawing.Point(); } } Output {X=0,Y=0} {X=1,Y=0} {X=1,Y=1} {X=0,Y=1}
Notes, public static readonly. We can get an error from using public static readonly (or const) fields. Here are some errors that can be encountered.
Error 1: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer) Error 2: The type 'System.Drawing.Point' cannot be declared const
Notes, specification. The concept of using public static readonly fields to simulate constant class instances is shown in the C# specification itself. This technique is effective.

Tip: I recommend you check out the annotated C# language specification for the original example. It uses the Color class.

Color
ReadOnlyCollection. When you make a field reference of a collection readonly, just that reference itself is readonly. The elements inside are no different.

Thus: You cannot make a collection itself readonly with just the readonly keyword.

However: You can use the ReadOnlyCollection type, which wraps other collections and prevents writes.

ReadOnlyCollection
A summary. We considered a practical usage of the readonly keyword. Further we compared the performance of readonly and const in an object-oriented program.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls