مقدمه
به فصل یازدهم و بررسی ویژگیهای پیشرفتهتر زبان C# خوش آمدید. ما با نحوهی دسترسی به
عناصر یک آرایه یا List<T> با استفاده از براکت [] کاملاً آشنا هستیم. برای مثال، myArray[0]
اولین عنصر آرایه را به ما میدهد. اما آیا تا به حال فکر کردهاید که چگونه میتوانیم این
قابلیت را برای کلاسهای سفارشی خودمان نیز فراهم کنیم؟ ایندکسرها (Indexers)
ویژگی قدرتمندی در C# هستند که دقیقاً همین کار را انجام میدهند. یک ایندکسر به
اشیاء یک کلاس اجازه میدهد تا مانند یک آرایه یا کالکشن، ایندکسگذاری شوند. این کار دسترسی به
دادههای کپسولهشده در یک کلاس را بسیار طبیعیتر و شهودیتر میکند.
ایندکسر (Indexer) چیست؟
یک ایندکسر عضوی از کلاس است که به شما اجازه میدهد به یک شیء از آن کلاس مانند یک آرایه دسترسی
پیدا کنید. در واقع، ایندکسرها نوعی "پراپرتی هوشمند" هستند. آنها مانند پراپرتیها دارای
اکسسورهای get و set هستند، اما به جای یک نام مشخص، از کلمهی کلیدی this به همراه یک یا چند پارامتر در داخل براکت [] برای تعریف خود
استفاده میکنند. این پارامترها میتوانند از هر نوعی باشند، نه فقط int، که این ویژگی ایندکسرها
را بسیار انعطافپذیر میکند.
تعریف یک ایندکسر
سینتکس تعریف یک ایندکسر بسیار شبیه به پراپرتی است. بیایید با یک مثال ساده شروع کنیم. فرض کنید
کلاسی به نام Sentence داریم که یک جمله را در قالب آرایهای از کلمات ذخیره میکند. ما میخواهیم
بتوانیم به کلمات این جمله از طریق اندیس عددی آنها دسترسی پیدا کنیم.
Program.cs
public class Sentence
{
private string[] _words;
public Sentence(string text)
{
_words = text.Split(' ');
}
public string this[int wordIndex]
{
get { return _words[wordIndex]; }
set { _words[wordIndex] = value; }
}
}
در این کد، ما یک ایندکسر تعریف کردهایم که یک int به عنوان اندیس میپذیرد. اکسسور get کلمهی
موجود در آن اندیس از آرایهی داخلی _words را برمیگرداند و اکسسور set به ما اجازه میدهد تا
آن کلمه را تغییر دهیم.
استفاده از ایندکسر
اکنون میتوانیم از یک نمونهی کلاس Sentence مانند یک آرایه استفاده کنیم:
Program.cs
Sentence mySentence = new Sentence("Hello C# World");
string secondWord = mySentence[1];
Console.WriteLine(secondWord);
mySentence[0] = "Greetings";
Console.WriteLine(mySentence[0]);
ایندکسر با اندیس رشتهای
همانطور که گفته شد، اندیس یک ایندکسر محدود به اعداد صحیح نیست. شما میتوانید از هر نوعی، مانند
string، برای اندیس استفاده کنید. این قابلیت برای ساختن کلاسهایی که مانند یک دیکشنری عمل
میکنند، بسیار مفید است.
Program.cs
public class CookieJar
{
private readonly Dictionary<string, string> _cookies = new();
public string this[string cookieName]
{
get { return _cookies[cookieName]; }
set { _cookies[cookieName] = value; }
}
}
CookieJar myCookies = new CookieJar();
myCookies["username"] = "alice";
myCookies["theme"] = "dark";
Console.WriteLine($"Username from cookie: {myCookies["username"]}");
در این مثال، کلاس CookieJar به ما اجازه میدهد تا با استفاده از یک کلید رشتهای، به مقادیر
دسترسی پیدا کنیم. این سینتکس بسیار خواناتر و طبیعیتر از فراخوانی متدهایی مانند
GetCookie("username") است.
سربارگذاری ایندکسرها
درست مانند متدها، ایندکسرها نیز میتوانند سربارگذاری (overload) شوند. این یعنی
شما میتوانید چندین ایندکسر در یک کلاس داشته باشید، به شرطی که لیست پارامترهای آنها (تعداد یا
نوع اندیسها) متفاوت باشد.
Program.cs
public class Schedule
{
private string[] _dailyTasks = new string[7];
public string this[int dayIndex]
{
get { return _dailyTasks[dayIndex]; }
set { _dailyTasks[dayIndex] = value; }
}
public string this[string dayName]
{
get { int dayIndex = GetDayIndex(dayName); return this[dayIndex]; }
set { int dayIndex = GetDayIndex(dayName); this[dayIndex] = value; }
}
private int GetDayIndex(string name) { return 0; }
}
کلاس Schedule دو ایندکسر دارد: یکی که با عدد (0 تا 6) کار میکند و دیگری که با نام روز هفته
(مثلاً "Sunday"). این به کاربر کلاس اجازه میدهد تا از هر روشی که برایش راحتتر است، استفاده
کند.