C# OOP Properties


In C# Object-Oriented Programming (OOP), properties are a fundamental feature used to access and manipulate the data stored within objects while adhering to the principles of encapsulation. Properties act as intermediaries between fields (the internal state of a class) and the outside world, providing controlled access to the class's data.

Properties combine the flexibility of methods (with custom logic for getting or setting values) and the simplicity of accessing fields directly, but with added protection and functionality.

Key Points about Properties in C# OOP:

  1. Encapsulation:

    • Properties allow you to hide the internal implementation (i.e., the actual fields) while exposing a public interface to interact with the object’s data.
    • They help ensure that the internal state of an object is not directly accessed or modified from outside the class in an uncontrolled way.
  2. Getter and Setter Methods:

    • get accessor: Retrieves (reads) the value of a property.
    • set accessor: Assigns (writes) a value to a property, allowing additional validation or logic during the assignment.
    • Properties can have both accessors, or just one of them, depending on whether you want the property to be read-only, write-only, or both.
  3. Automatic Properties:

    • C# allows for auto-implemented properties, where the compiler automatically generates a backing field for you. These are ideal when you don’t need extra logic in the get or set accessors.
  4. Read-Only and Write-Only Properties:

    • Properties can be designed as read-only by only including a get accessor, or write-only by only including a set accessor.
  5. Properties vs Fields:

    • Fields are generally declared as private to prevent external code from directly accessing them.
    • Properties are declared public (or with other appropriate access modifiers) to provide controlled access to the underlying fields.
  6. Backed by Private Fields:

    • Properties often use private fields (also called backing fields) to store data internally while providing controlled access through the get and set accessors.

Syntax for Properties in C#:

1. Property with Custom Get and Set Logic:

class Employee { // Private field (backing field) private string name; // Property to access the name field public string Name { get { return name; // Get the value of the private field } set { // Set the value with validation if (!string.IsNullOrEmpty(value)) { name = value; } else { throw new ArgumentException("Name cannot be empty"); } } } }
  • In this example, the property Name allows controlled access to the private field name, ensuring that invalid data (like an empty string) cannot be assigned.

2. Auto-Implemented Properties:

Auto-implemented properties allow for concise syntax when no additional logic is needed in the get or set accessors.

class Employee { // Auto-implemented property public string Name { get; set; } }
  • In this case, the compiler automatically creates a hidden backing field, and you don’t need to explicitly declare it.

3. Read-Only Property:

A property can be made read-only by providing only a get accessor.

class Employee { private string name; // Read-only property public string Name { get { return name; } } // Constructor to initialize the read-only property public Employee(string name) { this.name = name; } }
  • This property allows the name field to be set only within the constructor but can be read from anywhere.

4. Write-Only Property:

A property can be made write-only by providing only a set accessor.

class Employee { private string password; // Write-only property public string Password { set { password = value; } // Only set, no get accessor } }
  • This is useful for sensitive data, such as passwords, where you only want to allow data to be written but not read directly.

Properties with Different Access Modifiers:

You can also have different access levels for the get and set accessors, such as making the get accessor public and the set accessor private:

class Employee { // Property with public getter and private setter public string Name { get; private set; } public Employee(string name) { Name = name; // Can only be set inside the class } }

In this example, the Name property can only be modified within the class, but it can be read from outside.

Key Benefits of Using Properties in OOP:

  1. Encapsulation and Data Protection:

    • Properties protect the internal state of an object by controlling how fields are accessed and modified. This prevents unexpected changes to an object’s data and enforces class invariants.
  2. Validation Logic:

    • You can include logic in the set accessor to validate input data before it gets assigned to a field. For example, a set accessor could ensure that an integer is positive, or that a string is not empty.
  3. Flexibility:

    • With properties, you can add additional functionality such as logging, event triggering, or other operations when getting or setting values, without exposing the implementation details.

Example: Employee Class with Properties

class Employee { // Private fields (backing fields) private string name; private int age; // Public property for name with validation public string Name { get { return name; } set { if (!string.IsNullOrEmpty(value)) { name = value; } else { throw new ArgumentException("Name cannot be empty"); } } } // Public property for age with validation public int Age { get { return age; } set { if (value > 0) { age = value; } else { throw new ArgumentException("Age must be greater than zero"); } } } } class Program { static void Main(string[] args) { Employee emp = new Employee(); // Set properties emp.Name = "John Doe"; emp.Age = 30; // Get properties Console.WriteLine(emp.Name); // Output: John Doe Console.WriteLine(emp.Age); // Output: 30 } }

Conclusion:

Properties in C# OOP provide a powerful way to encapsulate class fields and control access to them. By using properties, you can:

  • Protect the internal state of your objects.
  • Implement validation and other logic when reading or writing values.
  • Expose a clean, public interface to interact with your objects while keeping implementation details hidden.