Fields: when to use "private" or "readonly" in c# ?

·

7 min read

Most times we want to protect some fields in our program and as with all things, the situation determines the approach. Encapsulation has always been one of the cornerstones of object-oriented programming (OOP). The ability to choose which state or data we seek to share is what makes the OOP paradigm standout.

Whenever we seek to protect the data or state from outside our class, then using the private access modifier is an ideal choice.

using System;
using System.Text;
using System.Collections.Generic; 
using System.Linq;
using System.IO;

namespace playground
{


  using System;
using System.Text;
using System.Collections.Generic; 
using System.Linq;
using System.IO;

namespace playground
{

     class Program
    {

        static void Main(string[] args)
        {
            var s1 = new MyClass("2018");

            //error CS0122: 'MyClass._year' is inaccessible due to its protection level
            //System.Console.WriteLine(s1._year);

            //output 2018
            System.Console.WriteLine(s1.Year);

           //change year. sample out will be 202
           s1.Changeyear();
           System.Console.WriteLine(s1.Year);
        }


    }

    class MyClass
     {
            private  string _year;

            public MyClass(string wrd)
            {
                _year = wrd;
            }

            //changes the private field _year
            public void Changeyear()
            {
                _year = "2020";
            }

            public string Year
            {
            get{return _year; } 
            set{ _year = value; }
            }

     }

}

As expected, System.Console.WriteLine(s1._year); throws an error. However, any method in our class can still make modifications to our program as we saw with the Changeyear() method we created.

Basically, this shows we can modify the private fields within our class. However, sometimes this may have unintended consequences where changes are mistakenly made to a field.

In other to avoid being able to change set values, the readonly modifier suffices. Remember, a readonly field cannot be assigned to except in a constructor of the class or during a variable initializer.


using System;
using System.Text;
using System.Collections.Generic; 
using System.Linq;
using System.IO;

namespace playground
{

     class Program
    {

        static void Main(string[] args)
        {
            var s1 = new MyClass("2018");

            //error CS0122: 'MyClass._year' is inaccessible due to its protection level
            // System.Console.WriteLine(s1._year);

            //output 2018
            System.Console.WriteLine(s1.Year);

            //change year
            s1.Changeyear();
            System.Console.WriteLine(s1.Year);

        }


    }

    class MyClass
        {
            private  string _year;

            public MyClass(string wrd)
            {
                _year = wrd;
            }

            //changes the private field _year
            public void Changeyear()
            {
                _year = "2020";
            }

            public string Year
            {
            get{return _year; } 
            set{ _year = value; }
            }


        }

    class ReadOnlySample
    {
        readonly string year;

        /* remember we could have just initialized
        the year as so:  
        private  string _year = "2018";
        However, we will use a constructor. 
        */

        public ReadOnlySample(string wrd)
        {
            year = wrd;
        }

        public void GetYear()
        {
            System.Console.WriteLine(year);
        }
        public void ChangeYear()
        {
            year = "new";
            System.Console.WriteLine(year);
        }
    }



}

The code sample above will not compile if we do not comment out year = "new";. This is because c# does not permit reassigning readonly fields after they have been initialized either in a constructor or by variable initialization.

To conclude, whenever you do not want either the class members or classes outside your class to make changes to a field, then use the readonly modifier. If the goal is to allow the class members alone the ability to make changes, then use the private modifier.