Readonly. This C# keyword prevents a class field from being changed. Readonly fields are initialized at runtime. Readonly does not affect individual elements in a field like a List.
This C# modifier does not affect performance. It just enforces certain constraints in the compiler. This leads to greater program quality—but types like ImmutableList are still needed.
Tip The benefit here is that other code, or the code from team members, can't change the readonly field.
using System;
class Program
{
static void Main()
{
Manager manager = new Manager();
Console.WriteLine(manager.GetStartup());
}
}
class Manager
{
readonly DateTime _startup;
public Manager()
{
// Initialize startup time.
this._startup = DateTime.Now;
}
public DateTime GetStartup()
{
// We cannot modify the DateTime here.
return this._startup;
}
}9/26/2024 8:07:44 AM
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.
class Manager
{
readonly DateTime _startup = DateTime.Now;
public DateTime GetStartup()
{
return this._startup;
}
}
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.
Detail A readonly field cannot be assigned to (except in a constructor or a variable initializer).
class Program
{
static readonly int _code = 100;
static void Main()
{
_code = 200;
}
}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.
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();
}
}{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.
Info The concept of using public static readonly fields to simulate constant class instances is shown in the C# specification itself.
A static readonly field cannot be assigned to
(except in a static constructor or a variable initializer)The type 'System.Drawing.Point' cannot be declared const
Benchmark, readonly. Consider this simple benchmark of readonly and const ints. We try to determine if there is any performance benefit to using readonly (or avoiding it).
Version 1 This version of the code gets a readonly field from the class many times in a loop.
Version 2 Here we get an int field that is not readonly many times in a tight loop.
Detail We fetch a const value in the loop. So no field needs to be accessed in this version.
Result Using a field that is not readonly appears to be fastest. But logically the const should be as fast as anything.
using System;
using System.Diagnostics;
class Test
{
readonly int _value1;
int _value2 = 1;
const int _value3 = 1;
public Test()
{
_value1 = int.Parse("1");
}
public int GetValue1()
{
return _value1;
}
public int GetValue2()
{
return _value2;
}
public int GetValue3()
{
return _value3;
}
}
class Program
{
static void Main()
{
Test test = new Test();
const int m = 1000000000;
Stopwatch s1 = Stopwatch.StartNew();
// Version 1: access readonly.
for (int i = 0; i < m; i++)
{
if (test.GetValue1() != 1)
{
throw new Exception();
}
}
s1.Stop();
Stopwatch s2 = Stopwatch.StartNew();
// Version 2: access field.
for (int i = 0; i < m; i++)
{
if (test.GetValue2() != 1)
{
throw new Exception();
}
}
s2.Stop();
Stopwatch s3 = Stopwatch.StartNew();
// Version 3: access const.
for (int i = 0; i < m; i++)
{
if (test.GetValue3() != 1)
{
throw new Exception();
}
}
s3.Stop();
// Results.
Console.WriteLine(s1.ElapsedMilliseconds);
Console.WriteLine(s2.ElapsedMilliseconds);
Console.WriteLine(s3.ElapsedMilliseconds);
}
}562 ms readonly
300 ms int
555 ms const
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.
Summary. We considered a practical usage of the readonly keyword. Further we compared the performance of readonly and const in an object-oriented program.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Sep 26, 2024 (edit link).