Encapsulation and Properties in C#: Access Modifiers & Getters/Setters
1. Encapsulation and Properties Overview
Q: What is encapsulation in C#?
Encapsulation is an object-oriented programming principle that bundles data (fields) and methods within a class, controlling access to protect the data's integrity. In C#, encapsulation is achieved using access modifiers and properties to hide implementation details and expose only necessary interfaces.
Q: What are properties in C#?
Properties are special members of a class that provide controlled access to private fields using getter (get) and setter (set) methods. They act as an interface to read or modify data while enforcing validation or logic, supporting encapsulation.
Syntax:
public type PropertyName { get; set; } // Auto-implemented property
// OR
public type PropertyName {
get { return field; }
set { field = value; } // value is implicit parameter
}
Q: Why is encapsulation important?
- Protects data from invalid or unauthorized modifications.
- Hides implementation details, exposing only necessary functionality.
- Improves maintainability by allowing internal changes without affecting external code.
- Supports validation and logic through properties.
Q: How does encapsulation in C# differ from C/C++?
- C#: Uses properties for controlled access, managed memory, and type safety. No pointers.
- C++: Uses getter/setter methods or direct field access, manual memory management, and pointers.
- C: Lacks classes and properties, uses structs with direct access, no encapsulation.
- C# Advantage: Simplified, safer encapsulation with properties and automatic memory management.
2. Access Modifiers
Q: What are access modifiers in C#?
Access modifiers control the visibility and accessibility of class members (fields, properties, methods). C# provides:
public: Accessible from everywhere.private: Accessible only within the same class (default for fields).protected: Accessible within the same class and derived classes.internal: Accessible within the same assembly.protected internal: Accessible within the same assembly or derived classes in any assembly.private protected: Accessible within the same class and derived classes in the same assembly (C# 7.2+).
Q: How are access modifiers used in encapsulation?
Access modifiers hide internal data (e.g., private fields) and expose controlled interfaces (e.g., public properties or methods), ensuring encapsulation by restricting direct access to sensitive data.
Q: Can you give an example of encapsulation with access modifiers?
using System;
namespace Encapsulation
{
class BankAccount
{
// Private field
private decimal balance;
// Public property with validation
public decimal Balance
{
get { return balance; }
set
{
if (value >= 0)
balance = value;
else
throw new ArgumentException("Balance cannot be negative");
}
}
// Protected method (accessible in derived classes)
protected void LogTransaction(string type, decimal amount)
{
Console.WriteLine($"{type}: {amount:C}");
}
// Public method
public void Deposit(decimal amount)
{
if (amount > 0)
{
Balance += amount;
LogTransaction("Deposit", amount);
}
else
{
throw new ArgumentException("Deposit amount must be positive");
}
}
}
class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount();
account.Deposit(100.50m);
Console.WriteLine($"Current Balance: {account.Balance:C}");
// account.balance = -50; // Error: balance is private
}
}
}
Output:
Deposit: $100.50
Current Balance: $100.50
3. Getters and Setters (Properties)
Q: What are getters and setters in C#?
Getters and setters are the get and set accessors of a property, controlling how a field is read or modified:
- Getter (get): Returns the field's value or computed result.
- Setter (set): Assigns a value to the field, often with validation.
- Auto-implemented Properties: Use
{ get; set; }for simple properties, where C# creates a private backing field automatically.
Q: What are the types of properties in C#?
- Read-Write Property: Has both
getandset(e.g.,public int Age { get; set; }). - Read-Only Property: Has only
get(e.g.,public int Age { get; }). - Write-Only Property: Has only
set(rare, e.g.,public int Age { set; }). - Init-Only Property (C# 9.0+): Can only be set during object initialization (
{ get; init; }).
Q: How do properties improve over traditional getter/setter methods?
Properties provide a cleaner syntax, integrate with C#'s type system, and support modern features like auto-implementation and expression-bodied properties, making code more concise and maintainable compared to explicit getter/setter methods in C++ or Java.
Q: Can you give an example of properties with getters and setters in C#?
using System;
namespace Properties
{
class Employee
{
private string name;
private int salary;
// Auto-implemented property
public string Department { get; set; }
// Property with validation
public string Name
{
get => name; // Expression-bodied getter
set => name = string.IsNullOrEmpty(value) ? "Unknown" : value;
}
// Read-only property
public int Salary
{
get => salary;
private set => salary = value >= 0 ? value : 0; // Private setter
}
// Init-only property (C# 9.0+)
public int Id { get; init; }
public Employee(string name, int salary, int id)
{
Name = name;
Salary = salary; // Uses private setter
Id = id;
}
public void GiveRaise(int amount)
{
Salary += amount; // Uses private setter
}
}
class Program
{
static void Main(string[] args)
{
// Object creation with init-only property
Employee emp = new Employee("Krishna", 50000, 101)
{
Department = "IT"
};
Console.WriteLine($"Employee: {emp.Name}, ID: {emp.Id}, Dept: {emp.Department}, Salary: {emp.Salary:C}");
emp.GiveRaise(5000);
Console.WriteLine($"After raise, Salary: {emp.Salary:C}");
// emp.Id = 102; // Error: Id is init-only
// emp.Salary = -100; // Error: Salary has private setter
}
}
}
Output:
Employee: Krishna, ID: 101, Dept: IT, Salary: $50,000.00
After raise, Salary: $55,000.00
Q: How do properties in C# differ from C/C++?
- C#: Properties replace explicit getter/setter methods, support auto-implementation, and integrate with garbage collection.
- C++: Uses getter/setter methods or direct field access, no built-in property syntax.
- C: No properties, uses structs with direct access.
- C# Advantage: Cleaner, safer, and more expressive encapsulation with properties.
4. Common Mistakes & Best Practices
Q: Common mistakes?
Encapsulation:
- Exposing fields directly as
publicinstead of using properties. - Not validating inputs in setters, leading to invalid object states.
Access Modifiers:
- Using overly permissive modifiers (e.g.,
publicfor internal data). - Forgetting to restrict setters (e.g.,
private setorinit).
Properties:
- Misusing auto-implemented properties when validation is needed.
- Writing verbose getter/setter logic when expression-bodied properties suffice.
- Forgetting
initfor immutable properties in modern C#.
Q: Best practices?
Encapsulation:
- Always encapsulate fields with properties to control access.
- Keep internal data
privateunless explicitly needed. - Use methods or properties to expose behavior, not raw data.
Access Modifiers:
- Default to
privatefor fields andprivate setfor properties. - Use
protectedorinternalfor class hierarchies or assembly access. - Minimize
publicexposure to maintain encapsulation.
Properties:
- Use auto-implemented properties (
{ get; set; }) for simple cases. - Add validation in setters for data integrity.
- Use
initfor properties set only at object creation (C# 9.0+). - Prefer expression-bodied properties (e.g.,
get => field) for concise code.
General:
- Follow naming conventions (e.g., PascalCase for properties, camelCase for private fields).
- Use modern C# features (e.g., init-only properties, nullable reference types).
- Document properties with XML comments to clarify their purpose.