Access Modifiers
Access modifiers control the visibility of classes, fields, properties, and methods. They're essential for encapsulation - hiding internal details while exposing a clean public interface.
The Access Modifiers
| Modifier | Description |
|---|---|
public | Accessible from anywhere |
private | Accessible only within the same class |
protected | Accessible within the class and derived classes |
internal | Accessible within the same assembly (project) |
private protected | Accessible within the class and derived classes in same assembly |
public
Public members are accessible from anywhere:
csharp1class Person2{3 public string Name; // Accessible from anywhere45 public void SayHello()6 {7 Console.WriteLine($"Hello, I'm {Name}");8 }9}1011Person p = new Person();12p.Name = "Alice"; // OK - Name is public13p.SayHello(); // OK - SayHello is public
private
Private members are only accessible within the class:
csharp1class BankAccount2{3 private decimal _balance; // Only accessible inside this class4 private string _pin;56 public void Deposit(decimal amount)7 {8 if (amount > 0)9 {10 _balance += amount; // OK - inside the class11 }12 }1314 public decimal GetBalance()15 {16 return _balance; // OK - inside the class17 }18}1920BankAccount account = new BankAccount();21account.Deposit(100); // OK - Deposit is public22decimal bal = account.GetBalance(); // OK23// account._balance = 1000; // Error! _balance is private
Default Access
If no modifier is specified:
- Class members default to
private - Classes default to
internal
csharp1class Example2{3 int value; // private (no modifier)4 void DoSomething() // private (no modifier)5 {6 }78 public int PublicValue; // explicitly public9}
Encapsulation in Practice
Hide internal details, expose controlled access:
csharp1class Temperature2{3 private double _celsius; // Hidden implementation45 // Public interface6 public double Celsius7 {8 get => _celsius;9 set10 {11 if (value < -273.15)12 throw new ArgumentException("Below absolute zero!");13 _celsius = value;14 }15 }1617 public double Fahrenheit18 {19 get => _celsius * 9 / 5 + 32;20 set => Celsius = (value - 32) * 5 / 9;21 }2223 public double Kelvin24 {25 get => _celsius + 273.15;26 set => Celsius = value - 273.15;27 }28}2930Temperature temp = new Temperature();31temp.Celsius = 25;32Console.WriteLine($"F: {temp.Fahrenheit}"); // F: 7733Console.WriteLine($"K: {temp.Kelvin}"); // K: 298.15
Protected Members
Accessible in the class and its derived classes (inheritance):
csharp1class Animal2{3 protected string species;45 public void SetSpecies(string s)6 {7 species = s;8 }9}1011class Dog : Animal12{13 public void Bark()14 {15 Console.WriteLine($"{species} says: Woof!"); // OK - protected16 }17}1819Dog dog = new Dog();20dog.SetSpecies("Canine");21dog.Bark(); // Canine says: Woof!22// dog.species = "X"; // Error! protected not accessible from outside
Internal Members
Accessible within the same assembly (project):
csharp1// In the same project2internal class InternalHelper3{4 internal void DoWork()5 {6 Console.WriteLine("Working...");7 }8}910// In Program.cs (same project)11InternalHelper helper = new InternalHelper(); // OK12helper.DoWork(); // OK1314// From another project - not accessible
Best Practices
1. Start Private, Expose as Needed
csharp1class User2{3 // Private by default4 private int _id;5 private string _passwordHash;6 private DateTime _lastLogin;78 // Public interface9 public int Id => _id;10 public string Username { get; set; }11 public bool IsActive { get; set; }12}
2. Hide Implementation Details
csharp1class EmailService2{3 // Private helper methods4 private bool ValidateEmail(string email)5 {6 return email.Contains("@");7 }89 private string FormatMessage(string message)10 {11 return message.Trim();12 }1314 // Public interface - users only see this15 public void SendEmail(string to, string message)16 {17 if (!ValidateEmail(to))18 throw new ArgumentException("Invalid email");1920 string formatted = FormatMessage(message);21 // Send the email...22 Console.WriteLine($"Sent to {to}: {formatted}");23 }24}
3. Protect Invariants
csharp1class ShoppingCart2{3 private List<string> _items = new List<string>();4 private bool _isCheckedOut = false;56 public void AddItem(string item)7 {8 if (_isCheckedOut)9 throw new InvalidOperationException("Cart is checked out");10 _items.Add(item);11 }1213 public void Checkout()14 {15 if (_items.Count == 0)16 throw new InvalidOperationException("Cart is empty");17 _isCheckedOut = true;18 Console.WriteLine("Order placed!");19 }2021 // Read-only access to items22 public IReadOnlyList<string> Items => _items.AsReadOnly();23}
Complete Example
csharp1class PlayerCharacter2{3 // Private fields - internal state4 private int _health;5 private int _experience;6 private readonly int _maxHealth;78 // Public properties - controlled access9 public string Name { get; }10 public int Level { get; private set; }1112 public int Health13 {14 get => _health;15 private set => _health = Math.Clamp(value, 0, _maxHealth);16 }1718 public int MaxHealth => _maxHealth;1920 public bool IsAlive => _health > 0;2122 // Constructor23 public PlayerCharacter(string name, int maxHealth = 100)24 {25 Name = name;26 _maxHealth = maxHealth;27 _health = maxHealth;28 Level = 1;29 _experience = 0;30 }3132 // Public methods - the interface33 public void TakeDamage(int amount)34 {35 if (amount < 0) return;36 Health -= amount;37 OnHealthChanged();38 }3940 public void Heal(int amount)41 {42 if (amount < 0) return;43 Health += amount;44 OnHealthChanged();45 }4647 public void GainExperience(int xp)48 {49 if (xp < 0) return;50 _experience += xp;51 CheckLevelUp();52 }5354 // Private helper methods55 private void OnHealthChanged()56 {57 Console.WriteLine($"{Name}: HP {_health}/{_maxHealth}");58 if (!IsAlive)59 {60 Console.WriteLine($"{Name} was defeated!");61 }62 }6364 private void CheckLevelUp()65 {66 int xpNeeded = Level * 100;67 while (_experience >= xpNeeded)68 {69 _experience -= xpNeeded;70 Level++;71 _health = _maxHealth; // Restore health on level up72 Console.WriteLine($"{Name} leveled up to {Level}!");73 xpNeeded = Level * 100;74 }75 }7677 public void DisplayStats()78 {79 Console.WriteLine($"=== {Name} ===");80 Console.WriteLine($"Level: {Level}");81 Console.WriteLine($"Health: {_health}/{_maxHealth}");82 Console.WriteLine($"XP: {_experience}/{Level * 100}");83 }84}8586// Usage87PlayerCharacter hero = new PlayerCharacter("Hero", 100);88hero.TakeDamage(30);89hero.Heal(10);90hero.GainExperience(250); // Level up!91hero.DisplayStats();
Summary
In this lesson, you learned:
public: Accessible from anywhereprivate: Accessible only within the classprotected: Accessible in class and derived classesinternal: Accessible within the same project- Default access is
privatefor members,internalfor classes - Encapsulation hides implementation and protects data integrity
- Start private, expose only what's necessary
Now let's practice with hands-on workshops!