Understanding Properties in C#: Controlled Access to Class Data

Learn about properties in C# and their role in providing controlled access to class data. This tutorial explains how properties work, their use of `get` and `set` accessors, different property types (read-only, write-only, read-write), and how they enhance encapsulation and code maintainability.



Understanding Properties in C#

In C#, properties provide a way to access and manipulate the values of private fields within a class. They offer a controlled way to interact with an object's data, enhancing code organization and maintainability.

How Properties Work

Properties don't have their own storage location. Instead, they provide a way to get or set the values of underlying private fields. They improve encapsulation by hiding internal implementation details.

Properties use accessors (`get` and `set`) to define how values are retrieved and modified. The `get` accessor specifies how to retrieve the value, and the `set` accessor specifies how to modify the value. Properties can be read-only (only `get` accessor), write-only (only `set` accessor), or read-write (both accessors).

Example 1: Basic Property


public class Person {
    private string _name; // Private field
    public string Name { 
        get { return _name; } 
        set { _name = value; } 
    }
}

Example 2: Property with Logic

You can add logic within the `set` accessor to perform actions or validations when a value is assigned:


public class Person {
    private string _name;
    public string Name {
        get { return _name; }
        set { _name = value.ToUpper(); } // Converts to uppercase
    }
}

Example 3: Read-Only Property

A read-only property only has a `get` accessor. The value cannot be changed from outside the class:


public class MyClass {
    private int _counter;
    public int Counter { get { return _counter; } } // Read-only
}

Why Use Properties?

Properties are preferred over directly exposing fields because they:

  • Enforce encapsulation: Hide internal implementation details.
  • Allow for data validation: You can add logic to the `set` accessor to ensure valid values.
  • Provide flexibility: You can easily change the internal implementation without affecting external code.