C# Indexers

    1 Votes

C# indexers allow us to create classes which act like virtual arrays. The instances of the class can be accessed using the [] array access operator. The indexer in C# is similar to defining operator [] in C++, but is considerably more flexible. For classes that encapsulate array or collection like functionality, using an indexer allows the users of that class to use the array syntax to access the class.

The indexers allow instances of a class, struct or interface to be indexed just like arrays. Indexer get accessor returns a value and set accessor assigns the value. The keyword this is used to define the indexers. The keyword value is used to define the value which is assigned by the set indexer. It is not necessary that indexers have to be indexed by an integer value; it is up to us how to define the mechanism.

They can be overloaded and can have more than one formal parameter. For example: accessing a two-dimensional array. Let us have a look on the syntax:
public int this[int index] 
// Indexer declaration
{
// get and set accessors
}
public interface inter1
{
  int this[int index]
  {
     get; set; 
  } 
} 

 

How to use Indexers

The indexers are syntactic convenience that enables us to create a class, struct or interface where client applications can access just like as an array. They are frequently implemented in types whose main purpose is to encapsulate an internal collection or an array. Indexer not only simplifies the syntax for client applications but it also makes the class and its purpose more intuitive for other developers to understand.

Let us have an example to understand it better:

using System;
namespace ConsoleApplication1
{
   class IndexedFruits
   {
      private string [] namelist = new string[size];
      static public int size = 10;
      public IndexedFruits()
      {
         for (int i = 0; i < size; i++)
         namelist [i] = "Null";
      }
      public string this[int index]
      {
         get
         {
            string t;
            if( index >= 0 && index <= size-1 )
            {
               t = namelist [index];
            }
            else
            {
               t = "";
            }
            return ( t );
         }
         set
         {
            if ( index >= 0 && index <= size-1 )
            {
               namelist [index] = value;
            }
         }
      }
      static void Main(string[] args)
      {
         IndexedFruits f = new IndexedFruits ( );
         f [0] = "Apple";
         f [1] = "Banana";
         f [2] = "Lichi";
         f [3] = "Cherry";
         f [4] = "Orange";
         f [5] = "Pineapple";
         for (int i = 0; i < IndexedFruits.size; i++ )
         {
            Console.WriteLine (f[i]);
         }
         Console.ReadKey ();
      }
   }
}

Output:

Apple
Banana
Lichi
Cherry
Orange
Pineapple
Null
Null
Null
Null

Indexers in Overloading

The indexers can be overloaded and they can be declared with the multiple parameters and each parameter can be of different type. As we have already studied that it is not necessary that indexer should be integers they can be of other types also. Let us understand through example:

using System;
namespace ConsoleApplication1
{
   class IndexedFruits
   {
      private string[] namelist = new string[size];
      static public int size = 10;
      public IndexedFruits()
      {
         for (int i = 0; i < size; i++)
         {
            namelist[i] = "Null";
         }
      }
      public string this[int index]
      {
         get
         {
            string t; 
            if( index >= 0 && index <= size-1 )
            {
               t = namelist[index];
            }
            else
            {
               t = "";
            }    
            return ( t );
         }
         set
         {
            if( index >= 0 && index <= size-1 )
            {
               namelist[index] = value;
            }
         }
      }
      public int this[string name]
      {
         get
         {
            int index = 0;
            while(index < size)
            {
               if (namelist[index] == name)
               {
                return index;
               }
               index++;
            }
            return index;
         }
      }
      static void Main(string[] args)
      {
         IndexedFruits f = new IndexedFruits ( );
         f[0] = "Apple";
         f[1] = "Banana";
         f[2] = "Lichi";
         f[3] = "Cherry";
         f[4] = "Orange";
         f[5] = "Pineapple"; 
         //using the first indexer with int parameter
         for(int i = 0; i < IndexedFruits.size; i++)
         {
            Console.WriteLine (f[i]);
         }
         //using the third indexer with the string parameter
         Console.WriteLine (f["Cherry"]);
         Console.ReadKey ();
      }
   }
}

Output:

Apple
Banana
Lichi
Cherry
Orange
Pineapple
Null
Null
Null
Null
3

Indexers with Interfaces

The indexers can be declared with interfaces as the accessors of interface indexers are different from the accessors of the class indexers. They are different in following ways:

  • The interface accessors do not use modifiers.
  • They do not have a body.

The purpose of the accessor is to indicate whether the indexer is read-write, read-only or write only. Let us understand through example:

using System.IO;
using System;
public interface Interface1
{
    // Indexer declaration:
    int this[int index]
    {
        get;
        set;
    }
}
// Implementing the interface.
class IndexerClass : Interface1
{
    private int[] arr = new int[100];
    public int this[int index]   // indexer declaration
    {
        get
        {
            // The arr object will throw IndexOutOfRange exception.
            return arr[index];
        }
        set
        {
            arr[index] = value;
        }
    }
}
class Program
{
    static void Main()
    {
        IndexerClass test = new IndexerClass();
        Random rand = new Random();
        // Call the indexer to initialize its elements.
        for (int i = 0; i < 10; i++)
        {
            test[i] = rand.Next();
        }
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine ("The element {0} is:{1}", i, test[i]);
        }
            Console.ReadKey ();
    }
}

Output:

The element 0 is: 531438917
The element 1 is: 557339696
The element 2 is: 8661852
The element 3 is: 101958769
The element 4 is: 299397112
The element 5 is: 1994789661
The element 6 is: 811107773
The element 7 is: 778755578
The element 8 is: 95880376
The element 9 is: 887315566

Planning to do an MBA?
A quick all-in-one MBA entry manual for MBA Aspirants. Book covers
  • Possible MBA Tests & Exam Preparation
  • Tips to choose right MBA Program
  • Essay, Resume & Letter of Recommendation
  • MBA Interview Preparation
  • MBA Financial Planning
Price - 6.99$
 

Popular Videos

How to speak to people

How to speak so that people want to listen.

Got a tip or Question?
Let us know

Related Articles

C# Overview & Evolution of C# Language
Introduction of .NET Framework
C# Datatypes - Datatype Conversion, Boxing & Unboxing
C# Metadata, Metadata Tables and Benefits
C# - Common Language Intermediate (CIL)
C# - Class and Objects
C# Assembly - How to create and share assembly
C# Garbage Collection
C# Exception Handling - User-Defied Exceptions
C# Inheritance - Single, Hierarchical, Multilevel & Multiple Inheritance
C# Polymorphism - Static and Dynamic polymorphism
C# Abstract Classes
C# Structures
C# Delegates and Events
C# Collections
C# XML Read and Write
C# Windows Presentation Foundation (WPF)
Language Integrated Query (LINQ)