آموزش سی شارپ – index گذاری اپراتورها
در این جلسه از سری آموزشی برنامه نویسی سی شارپ قصد بررسی index گذاری اپراتورها را داریم.
حتما قبل از بررسی index گذاری اپراتورها نوشتهی مطالب قبلی این دورهی آموزشی را با هشتگ #دوره آموزشی_سی_شارپ در سایت ما را مطالعه کنید.
آموزش سی شارپ index گذاری اپراتورها
معرفی Conversion Operators
Conversion operator یک شیء از کلاس شما را به نوع دیگری که مد نظرتان است تبدیل میکند. دو حالت از conversion operator موجود است.
implicit و explicit که فرم کلی آنها به شکل زیر است:
public static operator implicit target-type(source-type v) { return value; } public static operator explicit target-type(source-type v) { return value; }
target-type مشخص کنندهی نوعی است که قصد دارید source-type را به آن تبدیل کنید و value مقدار کلاس، بعد از تبدیل است. Conversion operator اطلاعات را مطابق با target-type باز میگرداند. اگر conversion operator بهطور implicit مشخص شود، conversion بهصورت اتوماتیک انجام خواهد شد. اگر conversion بهصورت explicit تعریف شده، cast مورد نیاز است. نمیتوانید برای یک source-type و target-type هم implicit و explicit را تعریف کنید.
مثال:
class TwoD { int X, Y; public TwoD() { X = Y = 0; } public TwoD(int a, int b) { X = a; Y = b; } public static implicit operator int(TwoD op) { return op.X * op.Y; } } // Using : TwoD ob1 = new TwoD(2, 2); TwoD ob2 = new T TwoD(1, 1); int i = ob1 * 3; Console.WriteLine(i); i = ob1 - 3; Console.WriteLine(i); i = ob1 + ob2; Console.WriteLine(i); i = ob1; Console.WriteLine(i);
نکته:
محدودیتهایی که در conversion operators وجود دارد:
- در Target-type یا source-type در conversion بایستی از جنس همان کلاسی شود که conversion در آن تعریف شده است. برای مثال نمیتوانید تبدیل double به int را از نو تعریف کنید.
- نمیتوانید class type را به نوع دادهی object تبدیل کنید.
- نمیتوانید برای یک source-type و target-type هم تبدیل implicit و هم تبدیل explicit تعریف کنید.
- نمیتوانید از یک base class به یک derived class تبدیل انجام دهید.
- نمیتوانید برای یک class-type به/از interface تبدیل انجام دهید.
- علاوهبر این قوانین، برای انتخاب بین implicit یا explicit باید دقت کنید.
- implicit conversion باید زمانی مورد استفاده قرار گیرد که تبدیل کاملاً عاری از خطا شود
برای کسب اطمینان در این مورد از این دو قانون پیروی کنید:
- هیچ فقدان اطلاعاتی (مثل کوتاهسازی، سرریز، تغییر علامت و…) نباید رخ دهد.
- تبدیل نباید باعث بروز exception یا خطا در برنامه شود. اگر conversion نتواند این دو قانون را رعایت کند، باید از explicit conversion بهره ببرید.
Indexers
index گذاری آرایه از طریق اپراتور [ ] انجام میشود. تعریف کردن اپراتور [ ] برای کلاس نیز امکانپذیر است اما برای این منظور از operator method استفاده نکرده و در عوض از Indexer استفاده میکنیم. Indexer اجازه میدهد یک شیء مانند یک آرایه index گذاری شود. Indexerها میتوانند یک یا بیشتر از یک بعد شوند.
فرم کلی Indexer یک بعدی بهشکل زیر است:
element-type this[int index] { // The get accessor get { // return the value specified by index } // The set accessor set { // set the value specified by index } }
در اینجا، element-type مشخص کنندهی نوع عنصر indexer است. پارامتر index در واقع index عنصری که میخواهید به آن دسترسی پیدا کنید را مشخص میکند. توجه کنید که نیازی نیست حتماْ جنس پارامتر int شود اما استفاده از int در این مورد رایج است. درون بدنهی indexer کلمههای get و set را مشاهده میکنید که به هر کدام از آنها accessor گفته میشود. یک accessor مشابه یک متد است با این تفاوت که return-type و parameter ندارد. هنگامیکه از indexer استفاده میکنید این accessorها بهطور اتوماتیک فراخوانی میشوند. هر دوی accessorها index را بهعنوان پارامتر دریافت میکنند اگر indexer در طرف چپ تساوی قرار بگیرند، set accessor فراخوانی شده و یک مقدار به عنصری که توسط index مشخص شده است، اختصاص داده میشود. در غیر اینصورت get accessor فراخوانی شده و عنصر مشخص شده توسط index، return میشود. Set method یک پارامتر به اسم value دارد که شامل مقداری است که به یک index مشخص اختصاص داده میشود.
مثال:
class IndexerDemo { int[] arr; // reference to underlying array (backing store) public int Lenght; public IndexerDemo(int size) { arr = new int[size]; Lenght = size; } // Indexer public int this[int index] { // get accessor get { return arr[index]; } // set accessor set { arr[index] = value; } } } // Using : IndexerDemo ob = new IndexerDemo(4); ob[0] = 10; ob[1] = 20; ob[2] = 30; ob[3] = 40; for (int i = 0; i < ob.Lenght; i++) { Console.WriteLine(ob[i]); }
مثال:
برای اینکه این بحث به طور کامل واضح شود در مثال زیر روی get و set کنترل بیشتری اعمال کردهایم: class IndexerDemo { int[] arr; public int Length; public bool ErrFlag; public IndexerDemo(int size) { arr = new int[size]; Length = size; } public int this[int index] { get { if (Ok(index)) { ErrFlag = false; return arr[index]; } else { ErrFlag = true; return 0; } } set { if (Ok(index)) { ErrFlag = false; arr[index] = value; } else { ErrFlag = true; } } private bool Ok(int index) { if (index >= 0 && index < Length) return true; return false; } } // Using : IndexerDemo ob = new IndexerDemo(5); for (int i = 0; i < 10; i++) { ob[i] = i * 10; if (ob.ErrFlag) Console.WriteLine("ob[{0}] is out of bound!", i); else Console.WriteLine("ob[{0}]: {1}", i, ob[i]); }
یک کلاس این قابلیت را اضافه کنید تا بهشکل آرایه نیز بتوان از آن استفاده کرد.
به مثال زیر توجه کنید:
class IndexerDemo { public int this[int index] { get { if (index >= 1 && index <= 10) { return index * 10; } else return -1; } } } // Using : IndexerDemo ob = new IndexerDemo(); Console.WriteLine(ob[1]); Console.WriteLine(ob[2]); Console.WriteLine(ob[3]); Console.WriteLine(ob[11]); Console.WriteLine(ob[10]);
دو محدودیت دیگر برای Indexerها موجود است:
- بهدلیل اینکه indexerها در واقع storage location (محل ذخیره سازی) تعریف نمیکنند و به نوعی متد هستند. استفاده از آنها بهعنوان پارامتر ref و out غیرمجاز است.
- indexer نمیتواند بهصورت static تعریف شود.
نظرات خود را در ارتباط با “اپراتورها در سی شارپ” برای ما ارسال کنید تا در دورههای بعدی از نظرات شما برای بهبود سایت استفاده کنیم. خب این جلسه هم به پایان رسید باید به این نکته توجه کنید که مباحث بالا در برنامه نویسی تجاری اهمیت فراوانی دارد. برای استفاده از تمامی جلسات از هشتگ #دوره آموزشی_سی_شارپ در سایت ما استفاده کنید. منتظر جلسه ی بعدی دوره آموزشی سی شارپ بمانید.
ارسال پاسخ