Public vs Private vs Protected vs Internal in C#: Key Differences
public members are accessible from anywhere, private members only within the same class, protected members within the class and its subclasses, and internal members within the same assembly. These access modifiers control how and where class members can be used to protect data and design.Quick Comparison
Here is a quick overview of the main access modifiers in C# and their visibility scopes.
| Access Modifier | Visibility Scope | Accessible From | Typical Use Case |
|---|---|---|---|
| public | Anywhere | Any code in any assembly | Expose API or members widely |
| private | Within class only | Only inside the defining class | Hide implementation details |
| protected | Class and subclasses | Defining class and derived classes | Allow subclass access but hide from others |
| internal | Within assembly | Any code in the same assembly | Limit access to current project or module |
Key Differences
public members are the most open and can be accessed from any other code, even outside the project or assembly. This is useful for APIs or classes meant to be used broadly.
private members are the most restrictive, visible only inside the class they are declared in. This protects internal data and logic from outside interference.
protected members allow access within the class and any class that inherits from it, enabling controlled extension and reuse. internal members are accessible anywhere within the same compiled assembly, but not from outside, making it ideal for sharing code within a project but hiding it from external users.
Code Comparison
This example shows how private members restrict access inside the class, while public members are accessible everywhere.
public class Person { private string secret = "MySecret"; public string Name = "Alice"; public void ShowSecret() { System.Console.WriteLine(secret); // Allowed inside class } } public class Program { public static void Main() { Person p = new Person(); System.Console.WriteLine(p.Name); // Allowed: public // System.Console.WriteLine(p.secret); // Error: private p.ShowSecret(); // Allowed: public method accessing private member } }
Protected and Internal Equivalent
This example demonstrates protected access in a subclass and internal access within the same assembly.
public class Animal { protected string sound = "Roar"; internal string habitat = "Forest"; } public class Lion : Animal { public void MakeSound() { System.Console.WriteLine(sound); // Allowed: protected access } public void ShowHabitat() { System.Console.WriteLine(habitat); // Allowed: internal access } } public class Program { public static void Main() { Lion lion = new Lion(); lion.MakeSound(); lion.ShowHabitat(); } }
When to Use Which
Choose public when you want your class or member to be accessible from anywhere, such as public APIs or libraries.
Choose private to hide details that should not be accessed or changed outside the class, protecting your data and logic.
Choose protected when you want to allow subclasses to access or modify members but keep them hidden from other classes.
Choose internal to share members within the same project or assembly but prevent access from external assemblies, useful for modular design.
Key Takeaways
public for members accessible everywhere.private to hide members inside the class only.protected to allow access in subclasses.internal to restrict access to the same assembly.