# Access Modifiers in C#

* The access modifiers are used to control the accessibility of the `class`, `variable`, `method`, and `constructors` throughout the assembly (assembly is in java is known as packages).In other words, access modifiers are used to increase or decrease visibility throughout the assembly and classes in projects of C#.

* Using the access modifiers we can limit the others from accessing the elements they don't need to access in other classes and packages.

## Types of access modifiers in C# :
1. public
2. protected
3. Internal
4. private
5. protected internal
6. private protected

Let's understand each one of them below with the program :
1. `public`: The type or member can be accessed by any other code in the `same assembly` or `another assembly` that references it.

```cs
class PointTest
{
    public int x;
    public int y;
}

class MainClass4
{
    static void Main()
    {
        var p = new PointTest();
        // Direct access to public members.
        p.x = 10;
        p.y = 15;
        Console.WriteLine($"x = {p.x}, y = {p.y}");
    }
}
// Output: x = 10, y = 15
```
> Note: If you change the `public` access level to `private` or `protected`, you will get the error message: `'PointTest.y' is inaccessible due to its protection level.`

2. `protected`: The type or member can be accessed only by code in the same `class`, or in a `class` that is `derived` from that `class`.

```cs
class Point
{
    protected int x;
    protected int y;
}

class DerivedPoint: Point
{
    static void Main()
    {
        var dpoint = new DerivedPoint();

        // Direct access to protected members.
        dpoint.x = 10;
        dpoint.y = 15;
        Console.WriteLine($"x = {dpoint.x}, y = {dpoint.y}");
    }
}
// Output: x = 10, y = 15
```
> Note: If you change the access levels of `x` and `y` to `private`, the compiler will issue the error messages:

`'Point.y' is inaccessible due to its protection level.`

`'Point.x' is inaccessible due to its protection level.`

3. `internal`: The type or member can be accessed by any code in the `same assembly`, but `not` from `another assembly`.

```cs
public class BaseClass
{  
   internal static int intM = 0;  
}
public class TestAccess
{  
   static void Main()
   {  
      var myBase = new BaseClass();   
      BaseClass.intM = 444;    
   }  
}
```
> Note: Using this `internal` the visibility of the variable only in the same `assembly`.

4. `private`: The type or member can be accessed `only` by code in the `same class`.

```cs
class Employee2
{
    private string name = "FirstName, LastName";
    private double salary = 100.0;

    public string GetName()
    {
        return name;
    }

    public double Salary
    {
        get { return salary; }
    }
}

class PrivateTest
{
    static void Main()
    {
        var e = new Employee2();

        // The data members are inaccessible (private), so
        // they can't be accessed like this:
        //    string n = e.name;
        //    double s = e.salary;

        // 'name' is indirectly accessed via method:
        string n = e.GetName();

        // 'salary' is indirectly accessed via property
        double s = e.Salary;
    }
}
```
> Note: Using `private` the visibility of the variable `name` and `salary` only in the same class. We cant access them in the same assembly also. (Accessing them using the getter and setter methods is another concept known as `encapsulation`).

5. `protected internal`:The type or member can be accessed by any code in the assembly in which it's declared, or from within a `derived class` in `another assembly`.

```cs
// Assembly1.cs
public class BaseClass
{
   protected internal int myValue = 0;
}

class TestAccess
{
    void Access()
    {
        var baseObject = new BaseClass();
        baseObject.myValue = 5;
    }
}

// Assembly2.cs
class DerivedClass : BaseClass
{
    static void Main()
    {
        var baseObject = new BaseClass();
        var derivedObject = new DerivedClass();

        // Error CS1540, because myValue can only be accessed by
        // classes derived from BaseClass.
        // baseObject.myValue = 10;

        // OK, because this class derives from BaseClass.
        derivedObject.myValue = 10;
    }
}
```
> Note: This access modifier is a combination of both `protected internal` here the properties of both access specifiers are combined that is., it is accessible in the same `assembly` and another assembly's derived class.

6. `private protected`: The type or member can be accessed `only within its declaring assembly`, by code in the same `class`, or in a type that is `derived` from that `class`.

```cs
public class BaseClass
{
    private protected int myValue = 0;
}

public class DerivedClass1 : BaseClass
{
    void Access()
    {
        var baseObject = new BaseClass();

        // Error CS1540, because myValue can only be accessed by
        // classes derived from BaseClass.
        // baseObject.myValue = 5;

        // OK, accessed through the current derived class instance
        myValue = 5;
    }
}
```
Note: Like the `protected internal` this is also a combination of two access modifiers and 'private protected` combines the properties of both access modifiers that is., `private` and `protected`.  Unlike `private` using this, we can access the properties in `same `assembly`.

