Understanding C# Properties

Properties in C# are a special type of class member that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used like public data members, but they include additional logic in the form of get and set accessors.

Key Topics

What are Properties?

Properties in C# are used to provide controlled access to private fields in a class. They use get and set accessors to define how values are read from and assigned to fields.

Example: Basic Property Usage

public class Person
{
    // Private field
    private string name;

    // Public property to access the private field
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a new Person object
        Person person = new Person();
        
        // Set the Name property
        person.Name = "John";
        
        // Get the Name property and display it
        Console.WriteLine($"Name: {person.Name}");
    }
}

Output:

Name: John
                        

Explanation: The Name property provides controlled access to the private field name. The get accessor returns the value of the field, and the set accessor assigns a value to it.

Auto-Implemented Properties

Auto-implemented properties allow you to quickly define properties without explicitly writing the get and set accessors. The compiler automatically creates a private field for the property.

Example: Auto-Implemented Properties

public class Car
{
    // Auto-implemented property
    public string Model { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a new Car object
        Car car = new Car();
        
        // Set the Model property
        car.Model = "Toyota Corolla";
        
        // Get and display the Model property
        Console.WriteLine($"Car Model: {car.Model}");
    }
}

Output:

Car Model: Toyota Corolla
                        

Explanation: The Model property is auto-implemented, meaning the compiler creates the backing field automatically. This simplifies the code when no additional logic is needed in the get or set accessors.

Property Accessors (Get and Set)

Properties in C# can include additional logic in their get and set accessors, allowing you to control how values are retrieved and assigned.

Example: Adding Logic to Accessors

public class BankAccount
{
    private decimal balance;

    // Property with validation in set accessor
    public decimal Balance
    {
        get { return balance; }
        set 
        { 
            if (value >= 0)
                balance = value; 
            else
                Console.WriteLine("Balance cannot be negative.");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a new BankAccount object
        BankAccount account = new BankAccount();
        
        // Set a positive balance
        account.Balance = 500;
        Console.WriteLine($"Balance: {account.Balance}");
        
        // Try setting a negative balance
        account.Balance = -200;
    }
}

Output:

Balance: 500
Balance cannot be negative.
                        

Explanation: The Balance property contains additional logic in the set accessor to ensure that a negative balance cannot be assigned. When a negative value is provided, an error message is printed, but the balance remains unchanged.

Read-Only Properties

Read-only properties only include a get accessor, meaning their values can be retrieved but not modified.

Example: Read-Only Property

public class Employee
{
    private string employeeId;

    // Read-only property
    public string EmployeeID
    {
        get { return employeeId; }
    }

    // Constructor to set the employee ID
    public Employee(string id)
    {
        employeeId = id;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a new Employee object
        Employee employee = new Employee("EMP12345");
        
        // Get and display the EmployeeID
        Console.WriteLine($"Employee ID: {employee.EmployeeID}");
    }
}

Output:

Employee ID: EMP12345
                        

Explanation: The EmployeeID property is read-only, meaning its value can only be set through the constructor and retrieved using the get accessor. It cannot be modified outside the class.

Computed Properties

Computed properties are properties whose values are calculated based on other fields or properties. They are typically used in conjunction with get accessors.

Example: Computed Property

public class Rectangle
{
    public double Length { get; set; }
    public double Width { get; set; }

    // Computed property to calculate area
    public double Area
    {
        get { return Length * Width; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a new Rectangle object
        Rectangle rect = new Rectangle();
        rect.Length = 5;
        rect.Width = 3;
        
        // Get and display the area
        Console.WriteLine($"Area: {rect.Area}");
    }
}

Output:

Area: 15
                        

Explanation: The Area property is a computed property, meaning its value is calculated based on the values of Length and Width. The get accessor computes the area whenever the property is accessed.

Key Takeaways

  • Properties provide controlled access to private fields using get and set accessors.
  • Auto-implemented properties simplify the code when no extra logic is needed.
  • Properties can include validation or other logic in the get or set accessors.
  • Read-only properties only include a get accessor and cannot be modified outside the class.
  • Computed properties return calculated values based on other fields or properties.