TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# Readonly Fields

This C# article uses the readonly keyword. Readonly prevents changes to fields after initialization.

Readonly prevents fields from being changed.

Readonly fields can be initialized at runtime, unlike const values. Attempts to change them later are disallowed.

This C# modifier does not affect performance.

Public Static Readonly

Tip: When using readonly, consider instead the const modifier. Const is better in some program contexts.

Const

Example. In this example we use readonly to initialize a DateTime struct. We cannot set a const DateTime—this raises a compilation error. But we want to designate a DateTime field as unavailable for further changes.

Next: In this program we don't want to mistakenly reset the startup time. Using readonly prevents this.

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)

In this example, a new class of type Manager is instantiated. Internally, the Manager class has a constructor. In the constructor, the startup time is initialized. We can assign the readonly field here.

Constructor

Readonly keyword. The constructor takes the current time from the DateTime.Now property and assigns it to an unchangeable readonly DateTime field. You are not able to accidentally reassign the startup time.

DateTimeDateTime.Now

Tip: The benefit here is that other code, or the code from your 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.

Inline initialization. It is possible to use an inline initialization for readonly. This means that you do not need to put the starting value in a constructor explicitly. 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;
    }
}

Constants. In many situations, it is better to use constants instead. For example, if you have a value that was established outside of your program, such as by science or other research, it is better.

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

DLLs. When you use a const field or declaration, the C# compiler actually 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. Here we look at a simple benchmark of readonly and const ints. We also include a regular instance of int in the benchmark. The readonly int and the int field had equivalent performance. The const int was faster.

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#
    Iterations: 1000000000 (many)

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();
}

Performance results

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).

ReadOnlyCollection. You cannot make a collection itself readonly with just the readonly keyword. When you make a field reference of a collection readonly, just that reference itself is readonly. The elements inside are no different.

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

ReadOnlyCollection

Summary. We saw a practical usage of the readonly keyword, and also noted how the first two examples are compiled into IL. Finally, we compared the performance of readonly and const in an object-oriented program.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf