Lesson 12 — Access Modifiers in C# (public, private, protected, internal)

Access modifiers control the visibility and accessibility of classes, methods, and variables in C#.
They determine who can access what, ensuring security, data protection, and proper code structure.

In this lesson, you will learn:

  • All access modifiers in C#
  • When and where to use each
  • Practical examples
  • A full comparison table
  • Real-world analogies

🌟 What are Access Modifiers?

Access modifiers define:

Which parts of your code can access a class or its members.

They are essential for encapsulation, the first pillar of OOP.


🧱 List of Access Modifiers in C#

C# provides 6 access modifiers:

1️⃣ public
2️⃣ private
3️⃣ protected
4️⃣ internal
5️⃣ protected internal
6️⃣ private protected

Let’s understand each.


🔵 1️⃣ public — Accessible Everywhere

✔ Meaning:

Anyone can access it — from any class, file, or project.

Example:

public class Student
{
    public string Name;
}

When to use:

  • Properties or methods that must be accessed anywhere
  • APIs, libraries, and global utilities

🔒 2️⃣ private — Accessible Only Inside the Same Class

✔ Meaning:

No one outside the class can access it.

Example:

public class Student
{
    private int age;   // hidden

    public void SetAge(int value)
    {
        age = value;
    }
}

Used for:

  • Data hiding
  • Securing sensitive fields
  • Encapsulation

🟠 3️⃣ protected — Accessible in Parent & Child Classes

✔ Meaning:

Only the class itself and its derived classes can access it.

Example:

public class Animal
{
    protected void Eat()
    {
        Console.WriteLine("Eating...");
    }
}

public class Dog : Animal
{
    public void StartEating()
    {
        Eat();   // allowed
    }
}

Used for:

  • Inheritance
  • When child classes must see the member

🟡 4️⃣ internal — Accessible Within the Same Project

✔ Meaning:

Accessible anywhere inside the same assembly/project, but not outside it.

Example:

internal class Helper
{
    public void DoWork() { }
}

Used for:

  • Large enterprise projects
  • Hiding internal utilities from outside world

🟢 5️⃣ protected internal — protected + internal

✔ Meaning:

Accessible:

  • In the same project
  • In derived classes (even if in another project)

Example:

public class Base
{
    protected internal void Print() { }
}


🟣 6️⃣ private protected — private + protected

✔ Meaning:

Accessible only in:

  • Same class
  • Derived classes
  • But only if derived classes are in the same project

Example:

public class Base
{
    private protected void Show() { }
}


🔍 Summary Table — Access Modifiers in C#

ModifierSame ClassDerived ClassSame ProjectOutside Project
public
private
protected
internal
protected internal
private protected

🌈 Real-World Analogy

✔ private

Your locker — only you can open it.

✔ public

Your social media profile picture — everyone can see.

✔ protected

Family photo album — only family members (derived classes) can access.

✔ internal

Employees inside one company can access internal documents.

✔ protected internal

Employees + family (derived classes outside company) can access.

✔ private protected

Only close family inside your house.


🧩 Practical Example — Access Modifiers in Action

public class Employee
{
    private double salary;
    protected string department;
    internal string officeLocation;

    public void SetSalary(double amount)
    {
        salary = amount;
    }
}

public class Manager : Employee
{
    public void ShowDetails()
    {
        // department accessible (protected)
        Console.WriteLine(department);

        // salary NOT accessible (private) ❌
        // Console.WriteLine(salary);
    }
}


🧠 Best Practices for Access Modifiers

✔ Use private for fields
✔ Use public for methods & properties
✔ Use protected when child classes must access data
✔ Use internal for project-specific utility classes
✔ Avoid protected internal unless needed
✔ Use private protected for strict inheritance control


📝 Mini Exercise

Create a class Product with:

  • private field → price
  • public method → SetPrice()
  • protected method → CalculateDiscount()
  • internal method → PrintLabel()

Then create a derived class and test which members you can access.


🔍 FAQs (SEO Boost)

Q1: Which access modifier is default?

If not specified:

  • class → internal
  • class members → private

Q2: Can private members be inherited?

Yes, but they are not accessible in derived classes.

Q3: What is the difference between protected and private?

Protected allows access in child classes; private does not.

Q4: Should fields be public?

No. Always keep fields private and expose via properties.


🎉 Conclusion

Access modifiers are essential for:

✔ Encapsulation
✔ Security
✔ Clean architecture
✔ Controlled access
✔ Better maintainability

You now understand:

  • public
  • private
  • protected
  • internal
  • protected internal
  • private protected