In C#, access modifiers determine the visibility and accessibility of classes, methods, properties, and other members. Choosing the right modifier helps you control how your code is exposed and reused.
Here is a breakdown of each access modifier and when to use it.
🌍 public
Accessible from anywhere, both within the same assembly and from other referenced assemblies.
Used when the member needs to be completely open to other codebases.
public class Logger {
public void Write(string message) { ... }
}
🔒 private
Accessible only within the same class or struct. If you omit a modifier, the member defaults to private.
Useful for implementation details that must not be exposed.
class Logger {
private void FormatMessage() { ... }
}
🛡️ protected
Accessible within the same class and by derived classes.
Use this when designing for inheritance while keeping the method hidden from general usage.
class BaseClass {
protected void Setup() { ... }
}
🏠 internal
Accessible to any code within the same assembly, but not from another assembly.
Ideal for limiting access to components of the same project or module.
internal class Helper {
internal void Calculate() { ... }
}
🏠🛡️ protected internal
Accessible to:
Any code in the same assembly
Derived classes in any assembly
This combines both protected
and internal
.
protected internal void Init() { ... }
🧱 private protected
Accessible only by:
Derived classes that are within the same assembly
It offers the strictest combined visibility.
private protected void Configure() { ... }
📊 Summary Table
| Caller's Location | `public` | `protected internal` | `protected` | `internal` | `private protected` | `private` |
| -------------------------------------- | :------: | :------------------: | :---------: | :--------: | :-----------------: | :-------: |
| Same class | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Derived class (same assembly) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Non-derived class (same assembly) | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
| Derived class (different assembly) | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
| Non-derived class (different assembly) | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |
Final Tip:
Use access modifiers intentionally to protect internal logic, support inheritance when needed, and keep your code maintainable. Choosing the right visibility is a critical part of robust class design.