یک ایندکسر، به یک نمونه از یک کلاس یا struct این اجازه را میدهد که بتواند همانند یک آرایه، ایندکس شود! اگر ایندکسری برای یک کلاس تعریف شود، کلاس همانند یک آرایهی مجازی (virtual array) رفتار خواهد کرد. همانطور که میدانید، اپراتور دسترسی به آرایه در سی شارپ بصورت «[ ]» است که ما نیز میخواهیم چنین قابلیتی برای کلاس خود ایجاد کنیم! یعنی همانند آرایهها بتوان توسط ایندکسی، مقداری را تنظیم کرده یا بیرون کشید.
سینتکس
ایندکسرها تقریبا همانند ویژگیها (Properties) در داخل کلاس تعریف میشوند؛ سینتکس آن بصورت زیر است:
[access_modifier] [return_type] this [argument_list] { get { // get block code } set { // set block code } }
- access_modifier: سطح دسترسی به ایندکسر که میتواند public, private و … باشد.
- return_type: نوع مقدار بازگشتی از ایندکسر
- this: کلمه کلیدی که به نمونهی فعلی ساخته شده از کلاس اشاره دارد.
- argument_list: پارامترهای ایندکسر
- get و set: همانند ویژگیها برای تنظیم مقدار و گرفتن مقدار
مثال: ایندسکر یک بعدی
فرض کنید کلاسی بنام FuLLKadeIndexer داریم و بصورت زیر؛ ایندکسر آن را پیاده کردیم:
class FuLLKadeIndexer { private string[] val = new string[3]; public string this[int index] { get { return val[index]; } set { val[index] = value; } } }
داخل این کلاس، یک آرایهی رشتهای تعریف شده که چهار خانه دارد؛ سپس ایندکسری تعریف کردیم که پارامتری از نوع int دریافت کرده و خروجی string بدهد. در بلاک get این ایندکسر، از طریق ورودی index، مقدار را از آرایهی رشتهای که در بالا تعریف کردیم بدست آورده و در set آن نیز مقدار را تغییر دادیم. البته هیچ اجباری نیست که حتما پارامتر ورودی ایندکسر عدد باشد، یا فقط یک ورودی داشته باشد، و یا اینکه حتما یک آرایه تعریف شود و ایندکسر به آن ارجاع داده شود! در واقع، ایندکسر تنها یک سینتکس است که میتوانیم برای اهداف مختلفی از آن استفاده کنیم.
در کد زیر، از کلاس بالا استفاده شده:
class Program { public static void Main() { FuLLKadeIndexer ic = new FuLLKadeIndexer(); ic[0] = "Hadi"; ic[1] = "Reza"; ic[2] = "FuLLKade"; Console.WriteLine("First Value = {0}", ic[0]); Console.WriteLine("Second Value = {0}", ic[1]); Console.WriteLine("Third Value = {0}", ic[2]); } }
در اینجا یک نمونه از کلاس ایجاد شده و همانند آرایهها، از [] برای دسترسی به ایندکسر استفاده کردیم. خروجی این کد، بصورت زیر خواهد بود:
First Value = Hadi Second Value = Reza Third Value = FuLLKade
- دو نوع ایندکسر وجود دارد: ایندکسر یک بعدی (One Dimensional Indexer) و ایندکسر چند بعدی (MultiDimensional Indexer)؛ که در کد بالا، به نوع یک بعدی آن اشاره شد. (یعنی فقط یک ورودی دریافت میکند.
- ایندکسرها نیز میتوانند اورلود (Overload) شوند.
- گرچه شبیه ویژگیها هستند، اما با آنها متفاوتند.
- ایندکسرها به آبجکتها امکان ایندکس شدن همانند آرایهها را میدهند.
- دسترسی set همواره برای تغییر مقدار و دسترسی get برای گرفتن مقدار استفاده میشود.
- کلمه کلیدی this همیشه باید در تعریف ایندکسرها استفاده شود.
- همانند ویژگیها، در داخل set، برای گرفتن مقدار وارد شده به ایندکسر، از کلمه کلیدی value استفاده میشود.
- از ایندکسرها گاها به عنوان آرایههای هوشمند یا آرایههای اسمارت (Smart Arrays) نیز یاد میشود. البته در برخی موارد Parameterized Property هم گفته میشود.
- ایندکسرها نمیتوانند استاتیک باشند و همیشه باید به آبجکت نسبت داده شوند.
مثال: ایندکسر دو بعدی
همانطور که گفته شد، مثال بالا یک ایندکسر یک بعدی است. اما برای تعریف ایندسکر چند بعدی، بایستی بیشتر از یک پارامتر برای آن تعیین کنیم. درواقع ایندکسرهای چند بعدی، تقریبا شبیه آرایههای چند بعدی هستند. به مثال زیر دقت کنید:
class FuLLKadeIndexer { int[,] data = new int[5, 5]; public int this[int index1, int index2] { get { return data[index1, index2]; } set { data[index1, index2] = value; } } }
دقیقا همانند مثال قبلی است؛ با این تفاوت که دو پارامتر ورودی برای ایندکسر تعریف کردیم. حالا بیایید از این کلاس استفاده کنیم؛ مثلا بصورت زیر:
class Program { public static void Main(String[] args) { FuLLKadeIndexer index = new FuLLKadeIndexer(); // مقداردهی به ردیف اول index[0, 0] = 1; index[0, 1] = 2; index[0, 2] = 3; // مقداردهی به بعد ردیف دوم index[1, 0] = 4; index[1, 1] = 5; index[1, 2] = 6; // مقداردهی به ردیف سوم index[2, 0] = 7; index[2, 1] = 8; index[2, 2] = 9; // چاپ مقادیر Console.WriteLine("{0}\t{1}\t{2}\n{3}\t{4}\t{5}\n{6}\t{7}\t{8}", index[0, 0], index[0, 1], index[0, 2], index[1, 0], index[1, 1], index[1, 2], index[2, 0], index[2, 1], index[2, 2]); } }
خروجی این:
1 2 3 4 5 6 7 8 9
مثال: ایندکسر فقط خواندی
بدون شک همانند ویژگیها میتوان یک ایندکسر را بصورت Read-Only در آورد؛ که در اینصورت، set حذف خواهد شد. به مثال زیر دقت کنید:
class FuLLKadeIndexer { public int this[int i1, int i2] { get { return (i1 + i2); } } }
در اینجا نه تنها ایندکسر بصورت «فقط خواندنی» درآمده است، بلکه خروجی آن نیز برخلاف قبل که به یک آرایه وابسته بود، این بار جمع دو ایندکس است! حالا برای مثال، بصورت زیر از این کلاس استفاده میکنیم:
class Program { public static void Main(String[] args) { FuLLKadeIndexer index = new FuLLKadeIndexer(); for (int i = 0; i <= 2; i++) { for (int j = 1; j <= 3; j++) { Console.Write(index[i, j] + "\t"); } Console.WriteLine(); } } }
در اینجا از 0 تا 2 شمرده و سپس داخل آن، هرکدام را با شمارشی دیگر از اعداد 1 تا 2، به داخل این ایندکسر ارسال و نتیجه را چاپ میکنیم. خروجی کلی بصورت زیر خواهد بود:
1 2 3 2 3 4 3 4 5
در بخش بعدی، به روش Overload یا اورلود کردن ایندکسرها میپردازیم!
نظرات ثبت شده بدون دیدگاه