Magical Role Of Indexer In C# Programming

Introduction

Indexer is an advanced feature of C# Language which enables us to build custom types that provide access to internal sub items using an array like syntax. The C# language provides the capability to design custom classes and structures that may index just like a standard array by defining.

Indexer Method

The most important things to know about the Indexer methods are the following,

Syntax of Indexer method

[ access modifier ]< space > [ return type ] < space > this[ parameter-type]
  1. {  
  2.    get;  
  3.    set;  
  4. }  
Example
  1. public string this[string value]  
  2. {  
  3.   get;  
  4.   set;  
  5. }  
Note:

It looks very similar to C# property except the parameter with this keyword, but it is quit different because it's a method while properties represent a field. Let's see the followings differences between Indexer and Property.
  • Indexer is defined by it's signature while property is defined by it's name
  • A property can be a static member whereas an Indexer is always an instance.
  • There is no name of Indexer method, it's accessible by the name of their Type either class, structure or interface
  • At the place of method name, it accepts keyword "this" with indexer operator( [ ] ) .
Remember:

Please mind that, by the convention indexer is a method but it is very different to a method/function because indexer must have at least one parameter and two indexer methods of a class could not have same parameter(s). Suppose we have an Indexer method with single parameter of integer type so we can not declare another method with the same type and parameter.

If we add multiple Indexer Methods with same type parameters, it will show compile time error. It doesn't care about return type, it's return type may be same or different but the parameter(s) never same. The following  snapshot of program in which we're trying to use parameters of two indexer methods with same type, says that "already defines a member called 'this' with same parameter types".

1_IndexerAndProperty

Example
  1. private List<People> myContactList = new List<People>();  
  2.   
  3. myContactList.Add(new People("Ram""ram@yahoo.com""9797225566""New Delhi"));  
  4. myContactList.Add(new People("Shyam""shyam@gmail.com""8484225599""Mumbai"));  
  5. myContactList.Add(new People("Rajesh""rajesh@yahoo.com""8888225458""New Delhi"));  
  6. myContactList.Add(new People("Dilip""dilip@facebook.com""7777225522""New Delhi"));  
  7. myContactList.Add(new People("Rama""rama@yahoo.com""9718185511""Delhi"));  
In the above code snippet we added five dummy records into a list
  1. private List < People > myContactList = new List < People > ();  
  2.   
  3. public People this[string peopleName]  
  4. {  
  5.     get  
  6.     {  
  7.         foreach(People p in myContactList)  
  8.         {  
  9.             if (p.FullName.ToLower() == peopleName.ToLower())  
  10.             {  
  11.                 peopleDetail = new People(p.FullName,  
  12.                     p.Email,  
  13.                     p.Contact,  
  14.                     p.City);  
  15.                 break;  
  16.             }  
  17.         }  
  18.         return peopleDetail;  
  19.     }  
  20. }  
The above code snippet is an example method for Indexer Method to find the people detail by their name. This method will return the search result for only one person whose name will match into the list of people, but the code snippet which is mentioned below will return the list of people whose name is same (eg. Name==Ram).
  1. private List<People> searchResultList = new List<People>();  
  2.   
  3. public List<People> this[string peopleName]  
  4. {  
  5.     get  
  6.     {  
  7.         foreach (People p in myContactList)  
  8.         {  
  9.             if (p.FullName.ToLower()==peopleName.ToLower())  
  10.             {  
  11.                 searchResultList.Add(p);  
  12.             }  
  13.         }  
  14.         return searchResultList;  
  15.     }  
  16. }  
Real Implementation of Indexer Methods

Let us create a demo application to know about the real implementation of indexer method. We will know about the implementation in indexer methods in Console Application & Web Application. So firstly we're going to create a class library type project where our entire logic of Indexer Methods resides, after that we will use the same logic in our both applications by referencing the .dll file.

Class Library

Now we are going to create a common project of type windows class library  which will help us to use the same logic into different applications. Because in this article we'll use this "Common Library Project" with the following type of applications:
  1. Console Application
  2. Web Application
Step 1: Create a class library project and add two classes with name "People and Phonebook". To create this project we may follow the following steps.

Image2

Step 2: 
Now add the class People and write the following properties inside the People class.

Code Snippet [ People ]
  1. //Class     
  2. public class People  
  3. {  
  4.     public string FullName  
  5.     {  
  6.         get;  
  7.         set;  
  8.     }  
  9.     public string Email  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  
  14.     public string Contact  
  15.     {  
  16.         get;  
  17.         set;  
  18.     }  
  19.     public string City  
  20.     {  
  21.         get;  
  22.         set;  
  23.     }  
  24.   
  25.   
  26.     public People(string fullName, string email, string contact, string city)  
  27.     {  
  28.         FullName = fullName;  
  29.         Email = email;  
  30.         Contact = contact;  
  31.         City = city;  
  32.     }  
  33. }  
Now add another class with name Phonebook, because in this application we will use the indexer method to search the contact from a phone book which contains a list of people with their name, contact, email and city.

Code Snippet [ Phonebook ]
  1. public class Phonebook  
  2. {  
  3.    private List<People> myContactList = new List<People>();  
  4.    private List<People> searchResultList = new List<People>();  
  5.    People peopleDetail;  
  6.    public Phonebook()  
  7.    {  
  8.        myContactList.Add(new People("Ram""ram@yahoo.com""9797225566""New Delhi"));  
  9.        myContactList.Add(new People("Shyam""shyam@gmail.com""8484225599""Mumbai"));  
  10.        myContactList.Add(new People("Rajesh""rajesh@yahoo.com""8888225458""New Delhi"));  
  11.        myContactList.Add(new People("Dilip""dilip@facebook.com""7777225522""New Delhi"));  
  12.        myContactList.Add(new People("Rama""rama@yahoo.com""9718185511""Delhi"));  
  13.    }  
  14. }
In the above code snippet, we have created a class with name "Phonebook" in which we have added five records into this phone-book. To add this record we have written this code inside the default constructor of class Phonebook, so we create the instance of class it will add these five records into a list.
 
In above code snippet, we have created an object named "myContactList" of type List<People> as well as added five dummy records into this collection. Now we're going to write some "Indexer methods" to access these records/contact list according to our indexer methods.

1. Add an Indexer method within the class Phonebook to display all contacts list.  
  1. //1. Indexer Method: To show all records    
  2. public List < People > this[bool isShowAll]  
  3. {  
  4.     get  
  5.     {  
  6.         if (isShowAll == true)  
  7.         {  
  8.             foreach(People p in myContactList)  
  9.             {  
  10.                 searchResultList.Add(p);  
  11.             }  
  12.         }  
  13.         return searchResultList;  
  14.     }  
  15. }  

In the above code snippet we have added an indexer method with Boolean type parameter. According to this code snippet if we pass the parameter as "true" then it will display all records available into this phone-book otherwise nothing. 

2. Add another Indexer method to find the contact by the name of people.
  1. public class Phonebook  
  2. {  
  3.   
  4.     private List < People > searchResultList = new List < People > ();  
  5.     private List < People > myContactList = new List < People > ();  
  6.   
  7.     //2. Indexer Method: To show record by name    
  8.     public People this[string peopleName]  
  9.     {  
  10.         get  
  11.         {  
  12.             foreach(People p in myContactList)  
  13.             {  
  14.                 if (p.FullName.ToLower() == peopleName.ToLower())  
  15.                 {  
  16.                     peopleDetail = new People(p.FullName,  
  17.                         p.Email,  
  18.                         p.Contact,  
  19.                         p.City);  
  20.                     break;  
  21.                 }  
  22.             }  
  23.             return peopleDetail;  
  24.         }  
  25.     }  
  26. }  

This indexer method will display the record which Name match (exact match) with input parameter otherwise not.

3. Add another Indexer method to search the record by the name or city of people,

  1. public class Phonebook  
  2. {  
  3.   
  4.     private List < People > searchResultList = new List < People > ();  
  5.     private List < People > myContactList = new List < People > ();  
  6.   
  7.     //3. Indexer Method: To show record by match by name or city    
  8.     public List < People > this[string peopleName, string cityName]  
  9.     {  
  10.         get  
  11.         {  
  12.             foreach(People p in myContactList)  
  13.             {  
  14.                 if (p.FullName.Contains(peopleName))  
  15.                 {  
  16.                     searchResultList.Add(p);  
  17.                 }  
  18.                 else if (p.City.Contains(cityName))  
  19.                 {  
  20.                     searchResultList.Add(p);  
  21.                 }  
  22.   
  23.             }  
  24.             return searchResultList;  
  25.         }  
  26.     }  
  27.   
  28. }   

Now our project library is ready to use with any project. The following are the complete code snippet which is written inside this project library.

[Code Snippet]

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7.   
  8. namespace MyPhonebook  
  9. {  
  10.     //Class   
  11.     public class People  
  12.     {  
  13.         public string FullName { getset; }  
  14.         public string Email { getset; }  
  15.         public string Contact { getset; }  
  16.         public string City { getset; }  
  17.           
  18.   
  19.         public People(string fullName, string email, string contact, string city)  
  20.         {  
  21.             FullName = fullName;  
  22.             Email = email;  
  23.             Contact = contact;  
  24.             City = city;  
  25.         }  
  26.     }  
  27.   
  28.     //Class  
  29.     public class Phonebook  
  30.     {  
  31.         private List<People> myContactList = new List<People>();  
  32.         private List<People> searchResultList = new List<People>();  
  33.         People peopleDetail;  
  34.   
  35.         public Phonebook()  
  36.         {  
  37.             myContactList.Add(new People("Ram""ram@yahoo.com""9797225566""New Delhi"));  
  38.             myContactList.Add(new People("Shyam""shyam@gmail.com""8484225599""Mumbai"));  
  39.             myContactList.Add(new People("Rajesh""rajesh@yahoo.com""8888225458""New Delhi"));  
  40.             myContactList.Add(new People("Dilip""dilip@facebook.com""7777225522""New Delhi"));  
  41.             myContactList.Add(new People("Rama""rama@yahoo.com""9718185511""Delhi"));  
  42.         }  
  43.   
  44.         /// <summary>  
  45.         /// Display all contacts list  
  46.         /// </summary>  
  47.         /// <param name="peopleName"></param>  
  48.         /// <returns></returns>  
  49.         public List<People> this[bool isShowAll]  
  50.         {  
  51.             get  
  52.             {  
  53.                 if (isShowAll == true)  
  54.                 {  
  55.                     foreach (People p in myContactList)  
  56.                     {  
  57.                         searchResultList.Add(p);  
  58.                     }  
  59.                 }  
  60.                 return searchResultList;  
  61.             }  
  62.         }  
  63.   
  64.         /// <summary>  
  65.         /// Searching by Name (By Exact match)  
  66.         /// </summary>  
  67.         /// <param name="peopleName"></param>  
  68.         /// <returns></returns>  
  69.         public People this[string peopleName]  
  70.         {  
  71.             get  
  72.             {  
  73.                 foreach (People p in myContactList)  
  74.                 {  
  75.                     if (p.FullName.ToLower() == peopleName.ToLower())  
  76.                     {  
  77.                         peopleDetail = new People(p.FullName, p.Email, p.Contact, p.City);  
  78.                         break;  
  79.                     }  
  80.                 }  
  81.                 return peopleDetail;  
  82.             }  
  83.         }  
  84.   
  85.   
  86.        /// <summary>  
  87.        /// Serching by Name or City (Returns exact macth or not)  
  88.        /// </summary>  
  89.        /// <param name="name"></param>  
  90.        /// <param name="cityName"></param>  
  91.        /// <returns></returns>  
  92.         public List<People> this[string peopleName, string cityName]  
  93.         {  
  94.             get  
  95.             {  
  96.                 foreach (People p in myContactList)  
  97.                 {  
  98.                     if (p.FullName.Contains(peopleName))  
  99.                     {  
  100.                         searchResultList.Add(p);  
  101.                     }  
  102.                     else if (p.City.Contains(cityName))  
  103.                     {  
  104.                         searchResultList.Add(p);  
  105.                     }  
  106.   
  107.                 }  
  108.                 return searchResultList;  
  109.             }  
  110.         }  
  111.           
  112.     }  
  113. }  
Web Application 

Now we're going to create a website in which we will put the reference of  the same library to know the usage of indexer method with web application.

Firstly we are going to add a website into current solution and add the reference of "MyPhonebook.dll" by "Right Click" on website and select "Add Reference..." from the popup window, after that a new window will appear on the screen where we may find and select our library .dll file.

Image3_Reference

Now we need to add a web page where we will call the Indexer methods to show the result for each type. Suppose we have added a Default.aspx page in our web application. Now add the following code inside the <form> tag,

  1. <form id="form1" runat="server">  
  2.     <div class="main-box">  
  3.         <h2>Indexer Method</h2>  
  4.         <p>Demo Application</p>  
  5.         <br />  
  6.         <div class="Filter">  
  7.             <asp:Button ID="btnAll" runat="server" CssClass="button" Text="All" OnClick="btnAll_Click"></asp:Button>  
  8.             <asp:Button ID="btnByName" runat="server" CssClass="button" Text="By Name" OnClick="btnByName_Click"></asp:Button>  
  9.             <asp:Button ID="btnByBoth" runat="server" CssClass="button" Text="Name & City" OnClick="btnByBoth_Click"></asp:Button>  
  10.         </div>  
  11.         <br style="clear: both;" />  
  12.         <table class="searchBox">  
  13.             <tr id="panelSearchByName" runat="server" visible="false">  
  14.                 <td>  
  15.                     <asp:TextBox ID="txtSerchByName" runat="server" placeholder="Name"></asp:TextBox>  
  16.                     <asp:Button ID="btnSearchByName" runat="server" Text="Go" OnClick="btnSearchByName_Click" />  
  17.                 </td>  
  18.             </tr>  
  19.             <tr id="panelSearchByNameandCity" runat="server" visible="false">  
  20.                 <td>  
  21.                     <asp:TextBox ID="TextBoxName" runat="server" placeholder="Name"></asp:TextBox>  
  22.                     <asp:TextBox ID="TextBoxCity" runat="server" placeholder="City"></asp:TextBox>  
  23.                     <asp:Button ID="btnByNameAndCity" OnClick="btnByNameAndCity_Click" runat="server" Text="Go" />  
  24.                 </td>  
  25.             </tr>  
  26.         </table>  
  27.         <p id="headingText" runat="server">All Contacts</p>  
  28.         <asp:Repeater ID="GridViewPhonebook" runat="server">  
  29.             <ItemTemplate>  
  30.                 <div class="record-list">  
  31.                     <img src="" alt="People Photo" />  
  32.                     <div class="right">  
  33.                         <span class="name"><%# DataBinder.Eval(Container.DataItem,"FullName") %></span>  
  34.                         <span class="mobile"><%# DataBinder.Eval(Container.DataItem,"Contact") %></span>  
  35.                         <span class="email"><%# DataBinder.Eval(Container.DataItem,"Email") %></span>  
  36.                         <span class="city"><%# DataBinder.Eval(Container.DataItem,"City") %> </span>  
  37.   
  38.                     </div>  
  39.                 </div>  
  40.             </ItemTemplate>  
  41.         </asp:Repeater>  
  42.         <asp:Label ID="Message" runat="server" Text="No Record Found" ForeColor="Red" Visible="false"></asp:Label>  
  43.     </div>  
  44. </form>   
Note:

I have used some style sheet classes to design the form layout which is not available in above code of Default.aspx page. To display the list of all records, write the following method at Default.aspx.cs page and call this method at Page_Load event.
  1. private void BindAllContact()  
  2. {  
  3.     List < People > myPhonebookList = phonebook[true];  
  4.   
  5.     if (myPhonebookList != null)  
  6.     {  
  7.         DataTable dataTable = new DataTable();  
  8.         dataTable.Columns.Add("FullName");  
  9.         dataTable.Columns.Add("Email");  
  10.         dataTable.Columns.Add("Contact");  
  11.         dataTable.Columns.Add("City");  
  12.   
  13.         foreach(People people in myPhonebookList)  
  14.         {  
  15.             dataTable.Rows.Add(people.FullName, people.Email, people.Contact, people.City);  
  16.         }  
  17.         GridViewPhonebook.DataSource = dataTable;  
  18.         GridViewPhonebook.DataBind();  
  19.         headingText.InnerText = "All Contact";  
  20.         Message.Visible = false;  
  21.     }  
  22.     else  
  23.     {  
  24.         Message.Visible = true;  
  25.     }  
  26. }  

In the above method we called the indexer method which accepts the single parameter of Boolean type, according to our logic which is written inside the indexer method, if you pass the parameter as true it will show the entire records otherwise no record.

Now call this method BindAllContact() on Page_Load, it will display the list of records like the following image.

The following image shows the list of all records which is available in our phonebook.

In this web page we have added the following three buttons according to our indexer methods.

  • All : (It shows all records)
  • By Name: (It shows the records whoes name match exactly)
  • By Name & City : (It shows the all records whose name or city match)

Search By Name

Now add the following methods at Default.aspx.cs and call this method on Button_Click on which you want to show the resultant list. For this article we will call this method on the click of button Go. 
  1. private void BindListByName(People people)  
  2. {  
  3.     headingText.InnerText = "Search Result";  
  4.     if (people != null)  
  5.     {  
  6.         DataTable dataTable = new DataTable();  
  7.         dataTable.Columns.Add("FullName");  
  8.         dataTable.Columns.Add("Email");  
  9.         dataTable.Columns.Add("Contact");  
  10.         dataTable.Columns.Add("City");  
  11.   
  12.         dataTable.Rows.Add(people.FullName, people.Email, people.Contact, people.City);  
  13.   
  14.         GridViewPhonebook.DataSource = dataTable;  
  15.         GridViewPhonebook.DataBind();  
  16.   
  17.         Message.Visible = false;  
  18.     }  
  19.     else  
  20.     {  
  21.         GridViewPhonebook.DataSource = null;  
  22.         GridViewPhonebook.DataBind();  
  23.         Message.Visible = true;  
  24.     }  
  25. }  
Search Result Output 


Now we'll search the name which is not available in this phonebook, it shows a message "No Record Found" which represents that the name we're trying to search is not available in this phonebook.


Serch By Name & City

Now add the following methods at Default.aspx.cs and call this method on Button_Click on which you want to show the resultant list. For this article we will call this method on the click of button Go.

[Code Snippet]

  1. private void BindListByNameAndCity(List < People > people)  
  2. {  
  3.     headingText.InnerText = "Search Result";  
  4.     if (people != null)  
  5.     {  
  6.         DataTable dataTable = new DataTable();  
  7.         dataTable.Columns.Add("FullName");  
  8.         dataTable.Columns.Add("Email");  
  9.         dataTable.Columns.Add("Contact");  
  10.         dataTable.Columns.Add("City");  
  11.   
  12.         foreach(People p in people)  
  13.         {  
  14.             dataTable.Rows.Add(p.FullName, p.Email, p.Contact, p.City);  
  15.         }  
  16.   
  17.         GridViewPhonebook.DataSource = dataTable;  
  18.         GridViewPhonebook.DataBind();  
  19.         Message.Visible = false;  
  20.     }  
  21.     else  
  22.     {  
  23.         GridViewPhonebook.DataSource = null;  
  24.         GridViewPhonebook.DataBind();  
  25.         Message.Visible = true;  
  26.     }  
  27. }   
Search Result Window


 
Console Application

Now we are going to create a console application in which we will use the class library to represent the "Indexer Methods".

Step I: 
Create a console application or add a new project into existing solution.

Step II: 
Now refer the class library project into this console application, to do so, we may follow the following steps. Right Click on application name and select "Add Reference..." and browse your library project.


Now we will see the following window, where we select our project,


Now we can see the our library project named "MyPhonebook" is listed under the references directory or our application.


 


 
 
 
 
  
 



Now call the Indexer method to display all records which is available into this phonebook.

[Code Snippet]

  1. {  
  2.     static void Main(string[] args)  
  3.     {  
  4.         Phonebook myPhonebook = new Phonebook();  
  5.   
  6.   
  7.         List < People > allPeople = myPhonebook[true];  
  8.         if (allPeople != null)  
  9.         {  
  10.             foreach(People p in allPeople)  
  11.             {  
  12.                 Console.WriteLine("Name: {0},\nE-mail:{1},\nContact: {2},      \nCity: {3}",  
  13.                     p.FullName,  
  14.                     p.Email,  
  15.                     p.Contact,  
  16.                     p.City);  
  17.                 Console.WriteLine("\n........");  
  18.             }  
  19.         }  
  20.         else  
  21.         {  
  22.             Console.WriteLine("\n No Contact Found.");  
  23.         }  
  24.         Console.ReadLine();  
  25.     }  
  26. }   

Output Window

Now call the indexer method to search the record whose Name is Ram.





Now we're going to call the indexer method to search the record whose name have "Ram" and city have "Delhi".

114

Search Result (in debug mode)

115

Summary

In this article we read about the "Indexer Methods" in C# programming, how it is different from a general method of C# as well as what are the benefits of Indexer Method.