C# Indexers. When do we use it ?
Tags: dotnet, csharp, dotnetcore, coding
Published: 2024-05-20 10:58:11

###### C# Indexers:
* C# indexers are like properties. It allows to access instances like an array with an index.
* It always represents collection objects but exposes arguments using which we can use to identify a particular element in the collection at a time.
* We can access an indexer by indexing the class instance with the appropriate index parameter.
* We can overload indexers with different data types and create multiple indexers for a class to expose & access different collections using the same class instance. 
* It acts as a member of a class but is used to access a data item of a collection from outside the class.

###### When do we use it? 
* Let's say we have to load a collection object in memory and we don't know upfront exactly how much memory it would take. Indexers help to set up an approach to load a small chunk of the entire data load,  process it, and then move on to the next chunk.
* It helps to abstract collection type in the model from the usage class as it always allows to access one data item at a time. This helps code easier to understand and maintain.
* Indexer should be used if providing an index to an object makes sense. 

###### Simple Example:

```c#

public class Employee
{
    public string Name{get;set;}
    public int Id {get;set;}
    public string Department{get;set;}
    public int DepartmentId{get;set;}
    public string City{get;set;}
    public string Zip{get;set;}
}

public enum DepartmentEnum{
    None = 0,
    Engineering,
    Accounting,
    Economics, 
    Politics
}

internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");

        var processor = new EmployeeProcessor(DepartmentEnum.Engineering);

        processor.ProcessPayroll();
        processor.ProcessHealthInsurance();

        Console.WriteLine($"Total engineering employees - {processor[DepartmentEnum.Engineering].Count()}"); 

        Console.ReadKey();
    }
}

public class EmployeeProcessor
{
    private List<Employee> employees = new List<Employee>();

    public EmployeeProcessor(DepartmentEnum department)
    {
        LoadEmployeesByDepartment(department);
    }

    public List<Employee> this[DepartmentEnum department]
    {
        get
        {
            return employees.Where(x=> x.DepartmentId == (int)department).ToList();
        }
    }

    private void LoadEmployeesByDepartment(DepartmentEnum department)
    {
        //load it from the data source. I am Hard coding for a blog 

        if(department == DepartmentEnum.Engineering)
        {
            employees.Add(
                new Employee()
                    {
                        Name = "Nirmal kumar",
                        Id = 1,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    });
        }
        else if(department == DepartmentEnum.Accounting)
        {
            employees.Add(new Employee()
            {
                Name = "Preethi",
                Id = 1,
                Department = "Accounting",
                DepartmentId = 2,
                City = "Atlanta",
                Zip = "12345"
            });
        }
        else if(department == DepartmentEnum.Economics)
        {
            employees.Add(new Employee()
            {
                Name = "Adithi",
                Id = 1,
                Department = "Economics",
                DepartmentId = 3,
                City = "New york",
                Zip = "23456"
            });
            employees.Add(new Employee()
            {
                Name = "Pranavi",
                Id = 2,
                Department = "Economics",
                DepartmentId = 3,
                City = "New york",
                Zip = "23456"
            });
        }
    }

    public void ProcessPayroll(){}

    public void ProcessHealthInsurance(){}
}

```