Click here to Skip to main content
Click here to Skip to main content

Indexers

, 11 May 2007
Rate this:
Please Sign up or sign in to vote.
A tutorial on indexers in C#

Introduction

Here we are going to introduce you to the concept of indexers in C#. Indexers can help simplify some programming aspects. Let us understand what these programming aspects are and then understand how indexers can help simplify them. To understand the programming aspects that indexers intend to simplify, we will go step by step with small programs.

What makes us use Indexers?

Let's write a simple C# program that implements a class named Maths and contains an entry point function Main().

P1.cs

class Maths
{
  public static void Main ()
  {
  }
} 

The program compiles successfully. Cool! Now let us add another class Number with a few private integers.

P2.cs

class Maths
{
  public static void Main ()
  {
  }
}

class Number
{
    private int _w;
    private int _x;
    private int _y;
    private int _z;
}

Output

b.cs(11,17): warning CS0169: The private field 'Number._w' is never used
b.cs(12,17): warning CS0169: The private field 'Number._x' is never used
b.cs(13,17): warning CS0169: The private field 'Number._y' is never used
b.cs(14,17): warning CS0169: The private field 'Number._z' is never used

The program compiles successfully but it throws warning messages. The warning says that we haven't used variables we declared. So it's time to remove the warning. For this we need to assign value to the variables. So let's define new public member functions to set the values of variables and get the values of variables.

P3.cs

class Maths
{
  public static void Main ()
  {
  }
}

class Number
{
    private int _w;
    private int _x;
    private int _y;
    private int _z;
   
    public static void Main ()
    {
    }

    public void set_x (int val)
    {
      _x = val;
    } 

    public int get_x ()
    {
      return _x;
    }

    public void set_y (int val)
    {
      _y = val;
    } 

    public int get_y ()
    { 
      return _y;
    }
    public void set_z (int val)
    {
      _z = val;
    } 

    public int get_z ()
    {
      return _z;
    }
    public void set_w (int val)
    {
      _w = val;
    } 

    public int get_w ()
    {
      return _w;
    }
} 

The program compiles successfully without a warning message. Function set_x() is used to set the value of variable _x and function get_x() is used to get the value of variable _x. Similarly, we have other set and get functions to set and get the vales of variables _y, _z and _w. Now let's put these functions to use.

P4.cs

class Maths
{
  public static void Main ()
  {
     Number num1 = new Number();
     num1.set_x(0);
     num1.set_y(10);
     num1.set_z(20);
     num1.set_w(30); 
 
     System.Console.WriteLine(num1.get_x());
     System.Console.WriteLine(num1.get_y());
     System.Console.WriteLine(num1.get_z());
     System.Console.WriteLine(num1.get_w());
  }
}

class Number
{
    private int _w;
    private int _x;
    private int _y;
    private int _z;
   
    public static void Main ()
    {
    }

    public void set_x (int val)
    {
      _x = val;
    } 

    public int get_x ()
    {
      return _x;
    }

    public void set_y (int val)
    {
      _y = val;
    } 

    public int get_y ()
    { 
      return _y;
    }
    public void set_z (int val)
    {
      _z = val;
    } 

    public int get_z ()
    {
      return _z;
    }
    public void set_w (int val)
    {
      _w = val;
    } 

    public int get_w ()
    {
      return _w;
    }
}

Output

0
10
20
30

In the above program we create an object num1 of class Number. Then we initialize the variables _x, _y, _z and _w using the set functions to values 10, 20, 30 and 0 respectively. Using the get functions we then print the values of variables _x, _y, _z and _w through the System.Console.WriteLine () function. The above program compiles and runs successfully to give the desired output.

Now let's come to the point. Wouldn't it have been convenient to access the member variables of the class Number like we access the members of an array as in:

for(int i = 0; i<4 ; i++)
    num1[i] = i*10;        

where 
num1[0] would represent variable _x
num1[1] would represent variable _y
num1[2] would represent variable _z
num1[3] would represent variable _w

instead of what we did in the above program as in:

num1.set_x(0);
num1.set_y(10);
num1.set_z(20);
num1.set_w(30);

Similarly, wouldn't it have been convenient to access the member variables of the class Number like we access the members of an array as in:

for(int i = 0; i<4 ; i++)
    System.Console.WriteLine(num1[i]);

where 
num1[0] would represent variable _x
num1[1] would represent variable _y
num1[2] would represent variable _z
num1[3] would represent variable _w

instead of what we did in the above program as in:

System.Console.WriteLine(num1.get_x());
System.Console.WriteLine(num1.get_y());
System.Console.WriteLine(num1.get_z());
System.Console.WriteLine(num1.get_w());

Certainly it would have been convenient to access the member variables of the class like we access the elements within the array. And this is made possible by the use of Indexers.

Let's use Indexers

class Demo
{
  public static void Main ()
  {
     Number num1 = new Number();
     num1.set_w(0);
     num1.set_x(40);
     num1.set_y(80);
     num1.set_z(120);
      
     System.Console.WriteLine(num1.get_w());
     System.Console.WriteLine(num1.get_x());
     System.Console.WriteLine(num1.get_y());
     System.Console.WriteLine(num1.get_z());
     
     for(int i = 0; i<4 ; i++)
        num1[i] = i*40;        

     for(int i = 0; i<4 ; i++)
        System.Console.WriteLine(num1[i]);  
  }
}

class Number
{
  private int _w;
  private int _x;
  private int _y;
  private int _z;

  public int this[ int indexer ]
  {
    get
    {
      if (indexer == 0)
         return _w;
      else if (indexer == 1) 
         return _x;
      else if (indexer == 2)
         return _y;
      else 
         return _z;
    }

    set
    {
      if (indexer == 0)
         _w = value;
      else if (indexer == 1) 
         _x = value;
      else if (indexer == 2)
         _y = value;
      else if (indexer == 3)
         _z = value;
    }   
  }

  public void set_x (int val)
  {
    _x = val;
  } 

  public int get_x ()
  {
    return _x;
  }

  public void set_y (int val)
  {
    _y = val;
  } 

  public int get_y ()
  {
    return _y;
  }
  public void set_z (int val)
  {
    _z = val;
  } 

  public int get_z ()
  {
    return _z;
  }
  public void set_w (int val)
  {
    _w = val;
  } 

  public int get_w ()
  {
    return _w;
  }
} 

Output

0
40
80
120
In set accessor of Indexer
In set accessor of Indexer
In set accessor of Indexer
In set accessor of Indexer
In get accessor of Indexer
0
In get accessor of Indexer
40
In get accessor of Indexer
80
In get accessor of Indexer
120

The above program compiles and runs successfully to give the desired output. Observe the code in bold. In the above program,

public int this[ int indexer ]
{
}

forms the indexer. The this is the keyword. The return type followed by the keyword this followed by integer argument within the square brackets forms the signature of an indexer. Like properties, the indexer has a set and a get accessor which are called as and when required. Indexers can also be overloaded like we overload functions.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Chetan Kudalkar
Software Developer (Senior)
India India
I am a Software engineer with around 7+ years of experience. Most of my experience is in Storage technology.

Comments and Discussions

 
GeneralPlease, improve article! PinmemberCuchuk Sergey25-Feb-08 20:20 
Questionplz clarify Pinmemberdurgasunil00712-Sep-07 3:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141216.1 | Last Updated 11 May 2007
Article Copyright 2007 by Chetan Kudalkar
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid