# A Beginner's Guide to C# Access Modifiers: Learn the Basics

Access modifiers determine the accessibility of a type or type member, indicating which parts of a C# program can access those types and their members. By protecting types and members from unintended access, access modifiers contribute to achieving encapsulation.

Below is the list of all the access modifiers used in the C# language

### Public

* type or members with `private` access modifiers could be accessed by any code in the same assembly or another assembly referencing it.
    
* `public` is the default access modifier for members of an `enum` or `interface`.
    
* accessibility of public members is controlled by the access modifier of the type itself.
    
    **Code example**
    
    ```csharp
    
    using System;
    namespace AccessModifierCode {
    class Employee {
    	public int EmpId;
    	public string Name;
    	public Employee(int empid, string name) {
    		EmpId = empid;
    		Name = name;
    	}
    }
    class Program {
    	static void Main(string[] args) {
    		// Creating object of the class Employee
    		Employee E = new Employee(1, "Deepak");
    		Console.WriteLine("Emp Id: {0}", E.EmpId);
    		Console.WriteLine("Name: {0}", E.Name);
    		Console.WriteLine();
    	}
     }
    }
    ```
    

### Private

* members declared with `private` access modifier are accessible only within the containing type.
    
* `private` access modifier is the most restrictive one.
    
* one can not declare a private class or struct directly inside a namespace.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689039479467/0191882f-b862-479f-a746-fa89d6ca9d9d.png align="center")
    
* `private` is the default accessibility for members of a class or struct.
    
    ```csharp
    public class Demo {
       string Name; //  private
    }
    ```
    
    ```csharp
    using System;
    namespace AccessModifierCode {
    class Employee {
    	public int EmpId;
    	public string Name;
        private decimal Salary
    	public Employee(int empid, string name, decimal salary) {
    		EmpId = empid;
    		Name = name;
            Salary = salary;
    	}
    }
    class Program {
    	static void Main(string[] args) {
    		// Creating object of the class Employee
    		Employee E = new Employee(1, "Deepak", 0);
    		Console.WriteLine("Emp Id: {0}", E.EmpId);
    		Console.WriteLine("Name: {0}", E.Name);
            Console.WriteLine("Salary: {0}", E.Salary); 
            // Error : 'Employee.Salary is inaccessible due to its protection level'
    		Console.WriteLine();
    	}
     }
    }
    ```
    

### Internal

* types or members declared with `internal` modifiers are accessible within the same assembly or friend assembly. Learn more about [Friend assembly](https://learn.microsoft.com/en-us/dotnet/standard/assembly/friend)
    
* `internal` is the default access modifier for class and struct types.
    

### Protected

`protected` type or members are accessible within the same class or derived class.

```csharp
public class Shape {
    protected int Width { get; set; }
    protected int Height { get; set; }
}
public class Rectangle : Shape {
    public Rectangle(int width, int height) {
        Width = width;
        Height = height;
    }
}
```

### protected internal

* Types or members declared with the `protected internal` modifier can be accessed only within the same assembly or in a derived class from another assembly.
    

### private protected

* A member that is `private protected` is accessible only within the containing type, or subclasses that reside in the same assembly (making it less accessible than protected or internal alone).
    

## Restrictions on Access Modifiers

* Interfaces declared directly within a namespace can be `public` or `internal` and, just like classes and structs, interfaces default to `internal` access.
    
* Interface members are `public` by default.
    
* Enumeration members are always `public`, and no access modifiers can be applied.
    
* Delegates function similarly to classes and structs. When declared directly within a namespace, they have `internal` access by default, and when nested, they have `private` access.
    
* Derived classes and derived records can't have greater accessibility than their base types. You can't declare a public class `B` that derives from an internal class `A`. If allowed, it would have the effect of making `A` public, because all `protected` or `internal` members of `A` are accessible from the derived class.
    

When overriding a base class function, accessibility must be identical to the over‐ ridden function.

```csharp
class BaseClass { 
    protected virtual void Foo() {} 
}
class Subclass1 : BaseClass { 
    protected override void Foo() {} // OK
} 
class Subclass2 : BaseClass { 
    public override void Foo() {} // Error
} 
```

## **Summary table**

| Caller's location | `public` | `protected internal` | `protected` | `internal` | `private protected` | `private` |
| --- | --- | --- | --- | --- | --- | --- |
| Within the class | ✔️️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Derived class (same assembly) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Non-derived class (same assembly) | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
| Derived class (different assembly) | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
| Non-derived class (different assembly) | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |

(note: copied from [MS learn](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers))

So, that concludes our discussion on access modifiers. In this article, we covered the six access modifiers in C#: public, private, protected, internal, protected internal, and private protected. We learned about the purpose of each access modifier and their applications.

By employing the appropriate access modifier, we can ensure that our code is secure, user-friendly, and easy to maintain. Ultimately, this allows us to establish a clear and consistent structure for our code.

**References and further reading**

* [https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers)
    
* [C# 10 in a Nutshell: The Definitive Reference](https://www.amazon.com/C-10-Nutshell-Definitive-Reference/dp/1098121953)
    
* [https://stackoverflow.com/questions/614818/in-c-what-is-the-difference-between-public-private-protected-and-having-no](https://stackoverflow.com/questions/614818/in-c-what-is-the-difference-between-public-private-protected-and-having-no)
