Encapsulation is a fundamental concept in object-oriented programming (OOP) that involves bundling the data (attributes) and methods (functions) that operate on the data into a single unit or class. It also restricts direct access to some of an object's components, which can prevent the accidental modification of data. This tutorial will cover encapsulation in C#, focusing on how to use access modifiers to control the visibility and accessibility of class members.
Encapsulation helps in protecting the integrity of the data by restricting its exposure to unauthorized access. In C#, this is achieved through the use of access modifiers, which define the scope and visibility of class members such as fields, properties, methods, and constructors.
C# provides several access modifiers that control the accessibility of class members:
Let's explore how these access modifiers work through practical examples.
public class Person
{
private string name;
private int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public void DisplayInfo()
{
Console.WriteLine($"Name: {name}, Age: {age}");
}
}
class Program
{
static void Main()
{
Person person = new Person("John Doe", 30);
person.DisplayInfo();
}
}
In this example, the `Person` class has two private fields, `name` and `age`, which are not accessible from outside the class. The constructor initializes these fields, and a public method `DisplayInfo` is provided to display their values.
### Example 2: Using Properties for Encapsulation
```csharp
public class Person
{
private string name;
private int age;
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set
{
if (value >= 0)
age = value;
else
throw new ArgumentException("Age cannot be negative.");
}
}
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public void DisplayInfo()
{
Console.WriteLine($"Name: {name}, Age: {age}");
}
}
class Program
{
static void Main()
{
Person person = new Person("John Doe", 30);
person.DisplayInfo();
// Accessing properties
person.Name = "Jane Doe";
person.Age = 25;
person.DisplayInfo();
}
}
In this example, the `Person` class uses properties (`Name` and `Age`) to encapsulate the private fields. Properties provide a way to get and set the values of the fields while allowing additional logic (like validation) to be executed.
### Example 3: Access Modifiers in Action
```csharp
public class Employee
{
public string Name { get; set; }
protected int Salary { get; set; }
public Employee(string name, int salary)
{
Name = name;
Salary = salary;
}
public void DisplayInfo()
{
Console.WriteLine($"Name: {Name}, Salary: {Salary}");
}
}
class Manager : Employee
{
public Manager(string name, int salary) : base(name, salary) {}
public void ShowSalary()
{
// Accessing protected member from derived class
Console.WriteLine($"Manager's Salary: {Salary}");
}
}
class Program
{
static void Main()
{
Employee emp = new Employee("Alice", 5000);
emp.DisplayInfo();
// emp.Salary; // This will cause a compile-time error as Salary is protected
Manager mgr = new Manager("Bob", 7000);
mgr.ShowSalary();
}
}
In this example, the `Employee` class has a public property `Name` and a protected property `Salary`. The `Manager` class, which inherits from `Employee`, can access the `Salary` property because it is protected. However, trying to access `Salary` directly from an instance of `Employee` outside the class hierarchy will result in a compile-time error.
## What's Next?
In this tutorial, we covered the basics of encapsulation in C# using access modifiers and properties. In the next section, we will delve deeper into "Access Modifiers in C#" to explore more advanced scenarios and best practices for controlling member visibility.