c# basics -encapsulation , properties- manual,auto-implemented, readonly ,static
Tags: beginners, csharp, dotnet
Published: 2020-08-06 14:46:14

Object oriented programming (**OOP**) focuses on modelling a business problem through objects. These objects are instances of a "Class". A **class** thus serves as a blueprint to create objects from. A class apart from being a piece of code, carries data and behavior the object must posses.The data fields are referred to as **properties** and the behavior are called as **methods** , together they are referred as **class members**. An important point to focus on here is one of the pillars of the OOP -Encapsulation. To encapsulate means to confine or encase something. In OOP we encapsulate a class by hiding its members. Here it is obvious to think, if we want to keep members hidden then why create the class in the first place ? However, when we create a class we have the liberty to expose the members. We decide which members should be accessible to the outside world , in view of this a class is also called as a "Contract". We are familiar with the access modifiers like private ,protected and public, which we decorate our class methods with. What about the data fields or the class properties ? Well, we expose them through *getters* and *setters*.Consider a class Employee, if we were to define a data field which holds an employee's name then the most basic way to do it manually as follows
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cyudltu3nmu9iqqy7dvq.png)

In here we are exposing the field *_employeeName* through the *public* property *EmployeeName* in Employee (class) contract . We see two pieces of information, 
``` get { }; set { };```. And mind you these are the most powerful tools we could use for our benefit. Since we are not directly exposing our data field *_employeeName* , we have a great level of control to validate the value we set for this at a field level ! For e.g. we could write much complex logic in the *set { }* block. We will get to it soon.
Another way to implement properties is to use the "autoimplemented" version provided by visual studio (when you use the snippet- prop. type prop and press tab).We use *auto-implemented* properties when we don't have to write any logic for getting or setting the data field - no validations or logic to get in the way- just plain simple accessing and setting the property. However an important thing to note here, behind the scenes the compiler creates a *backing field* for them as a default. Same can be seen for the  ```public int TimeHours { get; set; } ```. Below is the IL (Intermediate Language) code for TimeHours

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hpgcjzk2kmut835ri62s.JPG)

We could also make our properties *read-only* , the only thing we need to do is to have a *private set;* 
Say you have to calculate the pay for an employee. This salary depends on the hours the employee puts in and their designation. We don't want any external agent to set this value and our class is solely responsible to do this internally . We can achieve that through the following
```javascript
 public class Employee
    {
        private string _employeeName;

        public string EmployeeName
        {
            get
            {
                return _employeeName;
            }
            set
            {
                _employeeName = value;
                ;
            }
        }

        public int TimeHours { get; set; }
        public Designation EmployeeDesignation { get; set; }
        public double EmployeePay
        {
            get => CalculateEmployeePay();
            private set { }
        }

        private double CalculateEmployeePay()
        {
            switch (this.EmployeeDesignation)
            {
                case Designation.JuniorDeveloper: return TimeHours * 100;
                case Designation.MidLevelDeveloper: return TimeHours * 200;
                case Designation.SeniorDeveloper: return TimeHours * 300;
                default: return 0;
            }

        }
    }

    public enum Designation
    {
        JuniorDeveloper,
        MidLevelDeveloper,
        SeniorDeveloper
    }
```

Note that we have made the "setter" of property *EmployeePay* private thus making it *read-only*. We also introduced a logic in here by calling the method *CalculateEmployeePay* in the "getter" to return the employee's salary.

So far what we have discussed are "instance properties". They are specific to the object instance and are not shared between instances. If you recall, we said the class is a blueprint to create objects.These are also known as instances.
```javascript
            Employee emp1 = new Employee();
            emp1.EmployeeName = "Saania";
            emp1.EmployeeDesignation = Designation.MidLevelDeveloper;
            emp1.TimeHours = 10;

            Employee emp2 = new Employee();
            emp2.EmployeeName = "Hormaz";
            emp2.EmployeeDesignation = Designation.JuniorDeveloper;
            emp2.TimeHours = 2;
```
In the above snippet emp1 and emp2 are two separate instances of the Employee class with each having their own set of class members (properties+methods). If I make change to the EmployeeName property of the instance *emp1* then that is local to *emp1* and would not reflect in *emp2*. But what if there is a requirement that the Employee class holds a count for the total employees. Now this data would be global to an organization, we cannot have local copies for it. Say emp1 is our first employee and after instantiating it we do something like ```emp1.TotalEmployeeCount += 1``` then this change will be only confined to emp1 .When we create *emp2* a fresh instance would be created setting all its data-members to their defaults (effectively if we had a property TotalEmployeeCount then for emp2 its value would be 0 at the beginning) i.e. the effect of emp1 is totally lost. In such scenarios we opt for **static members**
**Static properties** are common between instances. Any change made to them is global. Also one thing to note is , the static properties cannot be accessed through the instances unlike the rest where we use the "." (dot) operator e.g ```emp2.EmployeeName = "Hormaz"; ``` . They are accessed through the class name. Let us create a static property which will help us maintain a count for all the employees.
```public static int TotalEmployees { get; set; } ``` . If we have to access them  then we will do that as ```Employee.TotalEmployees += 1; ```
It is also important to note that static data is not thread safe. Say this Employee class is a part of a larger distributed systems network. There are systems which modify the TotalEmployees count.It may happen so that two different systems try to modify the data at the same time. An obvious question would come to our mind that it is an atomic operation, we are just incrementing its count by one. We will go back to the autoimplemented properties concept. We saw that it is just a syntactic sugar for the manual property with a backing field. The compiler does  in fact creates a backing field for these properties. If we were to modify a property in essence it would be
1. read the value through "getter"
2. increment the value by 1
3. set the value through "setter"

It no longer is an atomic operation. There is a vulnerability that another thread (another process) gets access to its value before the previous one could increment and set the updated value. This leads to garbage data.