C# Encapsulation


Encapsulation is one of the fundamental principles of Object-Oriented Programming (OOP) in C#. It refers to the concept of bundling the data (fields) and the methods (functions) that operate on the data into a single unit, typically a class, while restricting direct access to some of the object's components. This allows control over the way data is accessed or modified, ensuring data integrity and security.

In C#, encapsulation is achieved using access modifiers such as private, protected, public, and internal. These modifiers control the visibility and accessibility of fields, properties, and methods of a class.

Key Concepts of Encapsulation:

  1. Data Hiding: Encapsulation allows you to hide the internal state of the object from the outside world. Only authorized methods can access and modify the data, ensuring that the object remains in a valid state.

  2. Access Modifiers: By using access modifiers, you control which parts of your class are accessible to external code. Common access modifiers include:

    • private: Members can only be accessed within the same class.
    • protected: Members can be accessed within the same class and by derived classes.
    • public: Members can be accessed from any other class.
    • internal: Members can be accessed within the same assembly (project).
  3. Getters and Setters (Properties): You can expose class fields in a controlled manner using properties. Properties allow you to define get and set methods to control how data is accessed and modified.

Example of Encapsulation in C#:

class Person { // Private field (encapsulated data) private string name; // Public property to access the private field in a controlled manner public string Name { get { return name; // Getter: returns the value of the private field } set { if (value.Length > 0) // Setter: adds validation logic { name = value; } else { throw new ArgumentException("Name cannot be empty."); } } } // Private field for age private int age; // Property to access and control the private age field public int Age { get { return age; } set { if (value > 0) // Validation logic for age { age = value; } else { throw new ArgumentException("Age must be a positive number."); } } } // Public method to display person's info public void DisplayInfo() { Console.WriteLine($"Name: {Name}, Age: {Age}"); } } class Program { static void Main() { Person person = new Person(); // Using encapsulation (via properties) to set and get private fields person.Name = "John"; // Valid input for name person.Age = 30; // Valid input for age person.DisplayInfo(); // Output: Name: John, Age: 30 } }

Explanation:

  1. Private Fields: In the Person class, the fields name and age are marked as private, meaning they cannot be accessed directly from outside the class.
  2. Public Properties: The class provides two public properties Name and Age to encapsulate access to these fields. The get accessor retrieves the field's value, while the set accessor contains logic to modify the field, such as validation (e.g., checking if the name is not empty and age is positive).
  3. Controlled Access: By using encapsulation, you control how name and age are accessed and modified. Invalid values cannot be assigned to these fields directly.

Benefits of Encapsulation:

  1. Data Protection: Encapsulation protects object data from unintended or invalid changes by restricting direct access to fields.
  2. Controlled Access: It provides controlled access through properties and methods, allowing for validation or additional logic before modifying fields.
  3. Modularity: The internal details of how data is managed are hidden from other parts of the application, reducing dependencies and improving modularity.
  4. Maintainability: It improves code maintainability by centralizing data access and modification logic within the class itself, making changes easier to implement.

Real-World Example:

Imagine you have a bank account system where the balance should only be modified by specific operations (like deposit and withdraw). Encapsulation ensures that no external code can directly modify the balance:

class BankAccount { private decimal balance; public decimal Balance { get { return balance; } } // Deposit method (encapsulated control) public void Deposit(decimal amount) { if (amount > 0) { balance += amount; } } // Withdraw method (encapsulated control) public void Withdraw(decimal amount) { if (amount > 0 && balance >= amount) { balance -= amount; } } }

In this example, balance is private and can only be modified via the Deposit and Withdraw methods, protecting it from accidental or malicious modification.

Conclusion:

  • Encapsulation is a powerful principle in C# OOP that helps to protect the internal state of an object by hiding its data and exposing it only through well-defined methods or properties.
  • It ensures data integrity, provides controlled access, and improves code maintainability.