درس هفدهم : انواع شمارشی در C#

در این درس با انواع شمارشی (Enumerator Types) در زبان C# آَشنا خواهیم شد. مطالب مورد بررسی در این درس به شرح زیر می‌باشند :

درک و فهم یک نوع شمارشی یا یک enum

ساخت یک نوع شمارشی جدید

چگونگی استفاده از انواع شمارشی

آشنایی با متدهای مختلف موجود در System.Enum

enmu فرم خاصی از انواع مقداری (Value Type) است که از System.Enum مشتق شده و امکان پیمایش درون مجموعه‌ای مشخص را با استفاد از اعداد صحصیح برای ما فراهم می‌نماید. با استفاده از enum می‌توان مجموعه‌ای از مقادیر ثابت را تعریف نمود که این مقادیر ثابت با استفاده از یک عدد صحیح قابل دسترسی هستند.

استفاده از enum در برنامه‌ها باعث بالا رفتن خوانایی برنامه می‌شود، چراکه با استفاده از آنها می‌توان با مجموعه‌ای از اعداد صحیح ترتیبی (Sequential) ، با عناوینی تعریف شده، کار کرد. برای مثال، در اعلان یک enum، ما مجموعه‌ای از نامهای مورد نظر را تعریف می‌نماییم و در برنامه می‌توانیم از این نامها بصورت ترتیبی استفاده نماییم. Enum به هر یک از عناصر موجود در این مجموعه عددی را تخصیص می‌دهد که شروع این عدد می‌تواند توسط برنامه‌نویس نیز معین گردد. سپس با استفاده از نام عناصر موجود در enum و یا با استفاده از اعدادی که به هر یک از این عناصر تخصیص داده شده، می‌توان enum را پیمایش نمود و به عناصر آن دسترسی داشت.

همانطور که گفته شد، enum یک نوع مقداری (Value Type) است، از اینرو ارث‌بری در مورد آن معنایی ندارد. مساوی قرار دادن دو enum نیز، مقادیر یکی را در دیگری کپی می‌کند. همانطور که در این درس، و در منابع دیگر، خواهید یافت، دسترسی به انواع شمارشی در C# با استفاده از دو کلمه enum و Enum امکان پذیر است. در C# نوع شمارشی enum از نوع BCL خود یعنی Enum ارث‌بری می‌کند ! با استفاده از enum یک نوع شمارشی جدید تولید می‌شود و با استفاده از Enum، می‌توان به پیاده‌سازی متدهای استاتیک انواع شمارشی پرداخت.

ایجاد یک نوع شمارشی

.Net Framework BCL حاویenum ها و مثالهای متعددی از استفادة آنها می‌باشد. برای مثال هرگاه که از MessageBox بر روی فرمی استفاده می‌شود، می‌توان از MessageBoxIcon که یک نوع شمارشی است استفاده نمود.

علاوه بر انواع شمارشی تعریف شده و موجود در .Net Framework، زمانهایی نیز وجود دارند که می‌خواهیم مجموعه‌ای از عناصر را تعریف کرده و از آنها استفاده نماییم. برای دسترسی به عناصری از نوع صحیح، استفاده از enum باعث خوانا شدن برنامه می‌گردد.

نحوه اعلان یک enum در حالت کلی بصورت زیر است :

<modifier> enum <enum_name>

            {

                        // Enumeration list

            {

در مثال 1-17 که در زیر ملاحظه می‌کنید، نحوه اعلان و استفاده از enum مشخص شده است.

مثال 1-17 : نحوه اعلان یک enum

using System;

// declares the enum
public enum Volume
{
   Low,
   Medium,
   High
}

// demonstrates how to use the enum

class EnumSwitch
{
   static void Main()
   {
      // create and initialize 
      // instance of enum type

      Volume myVolume = Volume.Medium;

      // make decision based
      // on enum value
      switch (myVolume)
      {
         case Volume.Low:
            Console.WriteLine("The volume has been turned Down.");
            break;
         case Volume.Medium:
            Console.WriteLine("The volume is in the middle.");
            break;
         case Volume.High:
            Console.WriteLine("The volume has been turned up.");
            break;
      }
      Console.ReadLine();
   }
}

در مثال 1-17 نمونه‌ای از اعلان یک enum را مشاهده می‌نمایید. همانطور که دیده می‌شود، اعلان یک نوع شمارشی با استفاده از کلمه کلیدی enum صورت گرفته و سپس به دنبال آن نام این مجموعه مشخص می‌شود. درون کروشه‌های باز و بسته { }   نیز، عناصر نوع شمارشی اعلان می‌گردند.

نوع شمارشی تولید شده در این مثال از نوع Volume است و در متد Main() از آن برای اعلان myVolume استفاده شده است. از آنجائیکه enum یک نوع مقداری است، می‌توانیم بطور مستقیم آنرا مقداردهی نماییم. پس از آنکه متغیر myVolume مقداردهی شد، می‌توان همانند سایر انواع مقداری، مانند int، از آن استفاده نمود. در حلقه switch، متغیر myVolume با عناصر enum مقایسه می‌شوند.

در هربار استفاده از عناصر enum تولید شده، از نام enum تولید شده، در اینجا Volume، در ابتدای نام عنصر استفاده می‌نماییم (Volume.Medium)، زیرا در صورتیکه در یک برنامه چندین enum وجود داشته باشند که دارای عناصری با نامهای یکسان باشند، در صورت عدم استفاده از نام enum مورد نظر قبل از عنصر، ابهام بوجود آمده و دچار مشکل می‌شویم.

بطور پیش فرض، به اولین عنصر تعریف شده در enum مقدار صفر تخصیص داده می‌شود که این مقدار تنها بعنوان اندیسی جهت دسترسی به این عنصر در نظر گرفته می‌شود. سایر عناصر enum نیز بطور صعودی مقدار می‌گیرند و به هر عنصر یک واحد افزوده می‌شود. در مثال 1-17، عنصر Low دارای اندیس صفر بوده و سایر عناصر به ترتیب مقدار 1 و 2 خواهند داشت.

در C#، برای موارد خاص می‌توان مقادیر پیش فرض در نظر گرفته شده برای عناصر enum را تغییر داد. به مثال زیر توجه کنید.

enum Months

     {

       jan, feb, mar, apr

     }

enum Months

     {

       jan = 10, feb = 20, mar = 30, apr=40 

     } 

همنطور که مشاهده می‌شود، در اعلان اول، از مقدار پیش فرض استفاده شده، که در این حالت jan = 0، feb = 1، mar = 2 و apr = 3 خواهند بود. اما در اعلان دوم، برنامه‌نویس بنا به نیاز خود، تشخیص داده تا به هر یک از عناصر enum مقداری دلخواه را نسبت دهد.

هر چند به تمامی عناصر enum مقداری نسبت داده می‌شود ولی از این مقدار نمی‌توان بطور مسقیم در تخصیص دهی مقدار به متغیری دیگر استفاده نمود. به مثال زیر توجه نمایید :

int x = Months.jan;// این دستور نادرست است

int x = (int) Months.jan ; //صحیح

برای استفاده از مقدار تخصیص داده شده به عناصر enum، باید از Casting استفاده نماییم. بدین معنا که باید نوع متغییری را که می‌خواهیم مقدار را به ان نسبت دهیم، باید مشخص شود. در مثال فوق (int) Months.jan معین می‌کند که مقدار تخصیص داده شده به jan به متغییری نسبت داده می‌شود که از نوع int است و یا به عبارت صحیح تر، مقدار تخصیص داده شده به عنصر enum، در فرمت int به متغییر مورد نظر تخصیص داده می‌شود.

در ادامه مبحث، توجه شما را به مثالی دیگر درباره enum جلب می نمایم. توجه نمایید که نکات جدیدی نیز در این مثال گنجانده شده اند.

مثال 2-17 : ساخت enum پایه و تخصیص دهی اعضای آن

using System;

// declares the enum

public enum Volume : byte

{

    Low = 1,

    Medium,

    High

}

class EnumBaseAndMembers

{

    static void Main()

    {

        // create and initialize

        // instance of enum type

        Volume myVolume = Volume.Low;

        // make decision based

        // on enum value

        switch (myVolume)

        {

            case Volume.Low:

                Console.WriteLine("The volume has been turned Down.");

                break;

            case Volume.Medium:

                Console.WriteLine("The volume is in the middle.");

                break;

            case Volume.High:

                Console.WriteLine("The volume has been turned up.");

                break;

        }

        Console.ReadLine();

    }

}

با توجه به مثال 2-17 با نحوه تغییر نوع پایه یک enum آشنا می شوید. همانطور که ملاحظه می نمایید، نوع پایه این enum به byte تغییر یافته است. این امر بیان میدارئ که تنها مقادیری از نوع byte قابل تخصیص به عناصر enum هستند.

همانطور که قبلا نیز اشاره شد، مقدار پیش فرض برای اولین عضو enum یعنی Low برابر با صفر است. چون در این مثال مقدار Low را برابر با یک قرار داده ایم، از اینرو مقادیر دو عضو دیگر آن نیز بصورت Middle=2 و High=3 تغییر خواهند یافت.

نکات پیشرفته درباره enum

در زبان C# هر نمونه از enum فضایی معادل با 4 بایت از حافظه را اشغال می نمایند. این مطلب با استفاده از کلمه کلیدی sizeof قابل بررسی لسا. از اینرو از enum میتوان به عنوان یک ساختمان داده مناسب و کارا یاد کرد.

نکته بسیار مهم و جالب در مورد enum در زبان برنامه نویسی C# انست که، برای هر کلاس enum موجود در کد برنامه، مقادیر رشته ای تخصیص داده شده به عناصر enum در یک اسمبلی و بصورت Metadata ذخیره می گردند، از اینرو دسترسی به این مقادیر رشته ای در کد میسر می شود. همچنین می توان از متدهای مختلف مرتبط با enum نیز استفاده نمود. به مثال ساده زیر توجه نمایید :

enum Language

{

    CSharp,MCpp,VBNet,JScript,IL

}

class App

{

    public static void Main()

    {

        Console.WriteLine("Write the number of the selected Language");

        string[] langAr = Enum.GetNames(Type.GetType("Language"));

        for(int i=0;i<langAr.Length;i++)

        {

            Console.WriteLine(i + "." + langAr[i]);

        }

        Language myLang=(Language)Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Your Language of choice is: " + myLang);

    }

}

  
نویسنده : ali gooliof ; ساعت ٤:٢٢ ‎ب.ظ روز ۱۳۸٧/٢/٦
تگ ها :