ایندکسر (Indexer)

فرض کنید یک کلاس به نام Person که دارای سه فیلد از نوع رشته است تعریف کرده‌ایم. همانطور که در داخل متد Main مشاهده می‌کنید می‌توان با استفاده از نام فیلدها به آنها دست یافت.

using System;

public class Person
{
    public string LastName;   
    public string FirstName;    
    public string CityOfBirth;        
}

class Program
{
   static void Main()
   {
      Person firstPerson = new Person();

      firstPerson.LastName = "Doe";
      firstPerson.FirstName = "Jane";
      firstPerson.CityOfBirth = "Dallas";

      Console.WriteLine("{0}", firstPerson.LastName);
      Console.WriteLine("{0}", firstPerson.FirstName);
      Console.WriteLine("{0}", firstPerson.CityOfBirth);
   }
}
Doe
Jane
Dallas

اما در نظر بگیرید، اگر با نمونه ایجاد شده از کلاس، مانند آرایه‌ای از فیلدها رفتار شود، که در این صورت دسترسی به فیلدها با استفاده از اندیس راحت‌تر است. این دقیقاً کاری است که ایندکسرها به شما اجازه انجام آن را می‌دهند. اگر بخواهید یک ایندکسر برای کلاس Person تعریف کنید باید کد داخل متد Main را به صورت زیر تعییر دهید. به این نکته توجه کنید که نمونه از علامت دات (.) برای دستیابی به فیلدها استفاده می‌کند، ولی ایندکسرها از اندیسی که در داخل کروشه وجود دارند.

static void Main()
{
    Person firstPerson = new Person();

    firstPerson[0] = "Doe";
    firstPerson[1] = "Jane";
    firstPerson[2] = "Dallas";

    Console.WriteLine( "{0}", firstPerson[0] );
    Console.WriteLine( "{0}", firstPerson[1] );
    Console.WriteLine( "{0}", firstPerson[2] );
}

تعریف ایندکسر

دستور تعریف ایندکسر به صورت زیر است. به نکاتی در مورد ایندکسرها توجه کنید :

از آنجاییکه همواره یک عضو نمونه است، نباید به صورت static تعریف شود.

ReturnType this [Type param1, ...]
{ 
   get 
   {
      ...
   }
   set
   {
      ...
   }
}

تعریف ایندکسر شبیه به تعریف خاصیت است. تفاوت و شباهت این دو به صورت زیر است :

بر خلاف خاصیت، ایندکسر :

  1. به جای نام دارای کلمه کلیدی this است.
  2. دارای لیستی از پارامترها است که در داخل یک جفت کروشه قرار دارند.

مانند خاصیت، ایندکسر :

  1. دارای نوع است.
  2. دارای متدهای get و set است

در مثال زیر یک Indexer برای کلاس Person تعریف می‌کنیم. از آنجاییکه این ایندکسر باید فیلدهایی از نوع رشته را مقداردهی کند نوع آن باید string باشد. در داخل این کلاس سه فیلد تعریف شده است و برای دسترسی به آنها از سه اندیس 0، 1 و 2 استفاده می‌کنیم، در نتیجه داخل کروشه باید از نوع int استفاده کنیم. در داخل بدنه set و get هم با استفاده از اندیس‌ها می‌توانیم مقادیری را به هر یک از فیلدها اختصاص بدهیم یا مقادیر را از آنها بخوانیم :

   1: using System;
   2: 
   3: public class Person
   4: {
   5:     public string LastName;         
   6:     public string FirstName;        
   7:     public string CityOfBirth;      
   8: 
   9:    public string this[int index]                                           
  10:    {                                                                       
  11:        set                                                                 
  12:        {                                                                   
  13:            switch (index)                                                  
  14:            {                                                               
  15:                case 0: LastName = value;                                   
  16:                    break;                                                  
  17:                case 1: FirstName = value;                                  
  18:                    break;                                                  
  19:                case 2: CityOfBirth = value;                                
  20:                    break;                                                  
  20:                    default: throw new ArgumentOutOfRangeException("index");
  21:            }                                                               
  22:        }                                                                   
  23:                                                                            
  24:        get                                                                 
  25:        {                                                                   
  26:            switch (index)                                                  
  27:            {                                                               
  28:                case 0: return LastName;                                    
  29:                case 1: return FirstName;                                   
  30:                case 2: return CityOfBirth;                                 
  20:                default: throw new ArgumentOutOfRangeException("index");    
  31:            }                                                               
  32:        }                                                                   
  33:    }                                                                       
  34: }
  35: 
  36: class Program
  37: {
  38:     static void Main()
  39:     {
  40:         Person firstPerson  = new Person();
  41:         Person secondPerson = new Person();
  42: 
  43:         firstPerson[0]  = "Doe";
  44:         firstPerson[1]  = "Jane";
  45:         firstPerson[2]  = "Dallas";
  46: 
  47:         secondPerson[0] = "Jack";
  48:         secondPerson[1] = "Rasel";
  49:         secondPerson[2] = "Chicago";
  50: 
  51:         Console.WriteLine("{0}", firstPerson[0]);
  52:         Console.WriteLine("{0}", firstPerson[1]);
  53:         Console.WriteLine("{0}", firstPerson[2]);
  54: 
  55:         Console.WriteLine("\n");
  56: 
  57:         Console.WriteLine("{0}", secondPerson[0]);
  58:         Console.WriteLine("{0}", secondPerson[1]);
  59:         Console.WriteLine("{0}", secondPerson[2]);
  60:     }
  61: }
Doe
Jane
Dallas


Jack
Rasel
Chicago