C# Properties and Indexers Explained

Explore practical examples of C# Properties and Indexers for better understanding.
By Jamie

Understanding C# Properties and Indexers

C# properties and indexers are integral features of the language that enhance encapsulation and provide a more intuitive way to access and manipulate data. Properties allow you to create a mechanism to read, write, or compute values, while indexers enable an object to be indexed like an array. Here are three practical examples to illustrate their use.

Example 1: Basic Property Implementation

Context

In this example, we will create a class called Person that uses properties to manage the state of a person’s name and age. This is a common use case where encapsulation is important for data integrity.

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)
                throw new ArgumentOutOfRangeException("Age cannot be negative.");
            age = value;
        }
    }
}

In this implementation, the Name and Age properties provide controlled access to the private fields name and age. The Age property includes validation to ensure that age cannot be set to a negative value.

Notes

  • Properties can have custom logic in their getters and setters, allowing for data validation or transformation.
  • Use properties to encapsulate data while exposing a clean interface to the users.

Example 2: Implementing an Indexer

Context

This example demonstrates how to create an indexer in a class representing a collection of books. This allows users to access books in the collection using array-like syntax.

public class BookCollection
{
    private List<string> books = new List<string>();

    public string this[int index]
    {
        get { return books[index]; }
        set { books[index] = value; }
    }

    public void AddBook(string book)
    {
        books.Add(book);
    }

    public int Count
    {
        get { return books.Count; }
    }
}

In this example, BookCollection uses an indexer to provide access to individual books in the books list. Users can add books and retrieve them using an index, enhancing the usability of the collection.

Notes

  • Indexers can be defined with multiple parameters, allowing for more complex structures.
  • Indexers provide a way to create more intuitive interfaces for collections and other data structures.

Example 3: Auto-Implemented Properties with Validation

Context

In scenarios where you want to create properties without explicitly declaring a backing field, auto-implemented properties are useful. This example demonstrates a class that uses them along with validation.

public class Product
{
    public string Name { get; set; }

    private decimal price;
    public decimal Price
    {
        get { return price; }
        set
        {
            if (value < 0)
                throw new ArgumentOutOfRangeException("Price cannot be negative.");
            price = value;
        }
    }
}

The Product class features an auto-implemented property for Name and a traditional property for Price, which includes validation to ensure that the price is not negative. This approach simplifies the code while maintaining the necessary encapsulation.

Notes

  • Auto-implemented properties reduce boilerplate code, making your classes cleaner.
  • You can still implement validation or custom logic in the setter of an auto-implemented property.

These examples of C# Properties and Indexers showcase their versatility and importance in creating structured, maintainable code. Understanding how to use them effectively will enhance your programming skills in C#.