عضو کانال یوتیوب ما شوید.

آموزش سی شارپ – 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;
   }
&nbsp;  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;
         }
      }
&nbsp;     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 تعریف شود.

 

نظرات خود را در ارتباط با “اپراتورها در سی شارپ” برای ما ارسال کنید تا در دوره های بعدی از نظرات شما برای بهبود سایت استفاده کنیم.

خب این جلسه هم به پایان رسید باید به این نکته توجه کنید که مباحث بالا در برنامه نویسی تجاری اهمیت فراوانی دارد.

برای استفاده از تمامی جلسات از هشتگ #دوره آموزشی_سی_شارپ در سایت ما استفاده کنید.

منتظر جلسه ی بعدی دوره آموزشی سی شارپ باشید.

برای امتیاز به این نوشته کلیک کنید!
[کل: 0 میانگین: 0]