Pages

Monday, 15 June 2015

Indexer

Indexer

Indexer is a pair of get and set accessors-similar to those of properties-which allow you to access field of a class using an index instead of using identifier. This way make you more convinience to access field within a class. For example let's see our person class.
 public class person
{      
 public string firstName;  
 public string lastName;
 public string address; 
 public string occupation;
}

class Program
{
 static void Main(string[] args)
 {
  person me = new person();
  me.firstName = "Yang";
  me.lastName = "Sopiana";
  me.address = "Bekasi";
  me.occupation = "Programmer";

  Console.WriteLine("Name : " + me.firstName + " " + me.lastName);
  Console.WriteLine("Address : " + me.address);
  Console.WriteLine("Ocupation : " + me.occupation);
 }
}

It will be more convinience if we write our main program like following:
class Program
{
 static void Main(string[] args)
 {
  person me = new person();
  me[0] = "Yang";     //use indexer 0 instead of accoundID
  me[1]= "Sopiana";    //use indexer 1 instead of accountFirstName
  me[2] = "Bekasi";    //use indexer 2 instead of accountLastName
  me[3] = "Programmer";   //use indexer 3 instead of accountBalance
  
  Console.WriteLine("Name : " + me[0] + " " + me[1]);
  Console.WriteLine("Address : " + me[2]);
  Console.WriteLine("Ocupation : " + me[3]);
 }
}

Indexer allows you to do that. You can create indexer with syntax below:
[Access Modifier : Optional][Type] this [int index]
{
 get
 {
  [Get Accessor's Statement ]
 }
 set
 {
  [Set Accessor's Statement ]
 }
}

Declaring the Indexer

The following code declares an indexer for the earlier example: class Employee.
public string this[int index]
{
 get
 {
  switch (index)
  {
   case 0: return firstName;
   case 1: return lastName;
   case 2: return address;
   case 3: return occupation;
   default:
    Console.WriteLine("index out of the bound");
    return "";
  }
 }
 set
 {
  switch (index)
  {
   case 0: firstName = value;
    break;
   case 1: lastName = value;
    break;
   case 2: address = value;
    break;
   case 3: occupation = value;
    break;
   default:
    Console.WriteLine("index out of the bound");
    break;
  }
 }
}

And with the following main function:
static void Main(string[] args)
{
 person me = new person();
 me[0] = "Yang";     //use indexer 0 instead of accoundID
 me[1] = "Sopiana";    //use indexer 1 instead of accountFirstName
 me[2] = "Bekasi";    //use indexer 2 instead of accountLastName
 me[3] = "Programmer";   //use indexer 3 instead of accountBalance

 Console.WriteLine("Name : " + me[0] + " " + me[1]);
 Console.WriteLine("Address : " + me[2]);
 Console.WriteLine("Ocupation : " + me[3]);
}

It will produce following display:
Name : Yang Sopiana
Address : Bekasi
Ocupation : Programmer

Characteristics of Indexer

Indexers and properties are similar in many ways.
  • Like a property, an indexer does not allocate memory for storage.
  • Both indexers and properties are used primarily for giving access to other data members with which they’re associated and for which they provide get and set access. But a property usually represents a single data member, but an indexer usually represents multiple data members.
  • Like a property, an indexer can have either one or both of the accessors.
But one thing we should remember is indexers are always instance members; hence, an indexer cannot be declared static.

Indexer Overloading

A class can have any number of indexers, as long as the parameter lists are different; it isn’t sufficient for the indexer type to be different. This is called indexer overloading, because all the indexers have the same "name"—the this access reference.

Let's add some fields to person.
public class person
{
 public string firstName;
 public string lastName;
 public string address;
 public string occupation;
 public int age;     //new added field
 public int familyMember;  //new added field
 ....
}

How can we access age and familyMember fields with indexer? They have different type with the indexer. The answer would be overloading.

We can overload the indexer that return different type and parameter list. See following code change.
....
public int this[string typeName,int index] //adding typeName is a way to overload, you can also change it with only string indexer
{
 get
 {
  if (typeName == "int")
  {
   switch (index)
   {
    case 0: return age;
    case 1: return familyMember;
    default: throw new ArgumentOutOfRangeException();
   }
  }
  else
   throw new ArgumentOutOfRangeException();
 }
 set
 {
  if (typeName == "int")
  {
   switch (index)
   {
    case 0: age = value;
     break;
    case 1: familyMember = value;
     break;
    default: throw new ArgumentOutOfRangeException();
   }
  }
  else
   throw new ArgumentOutOfRangeException();
 }
}
....
static void Main(string[] args)
{
 person me = new person();
 me[0] = "Yang";     //use indexer 0 instead of accoundID
 me[1] = "Sopiana";    //use indexer 1 instead of accountFirstName
 me[2] = "Bekasi";    //use indexer 2 instead of accountLastName
 me[3] = "Programmer";   //use indexer 3 instead of accountBalance
 me["int", 0] = 29;    //use indexer "int" and 0 instead of age
 me["int", 1] = 3;    //use indexer "int" and 0 instead of familyMember

 Console.WriteLine("Name : " + me[0] + " " + me[1]);
 Console.WriteLine("Address : " + me[2]);
 Console.WriteLine("Ocupation : " + me[3]);
 Console.WriteLine("Age : " + me["int", 0]);
 Console.WriteLine("Family Member : " + me["int", 1]);
}

When you compile modified code, you will see:
Name : Yang Sopiana
Address : Bekasi
Ocupation : Programmer
Age : 29
Family Member : 3

0 comments:

Post a Comment