دسته بندی وبلاگ

 
 

داده های شمارشی در سی شارپ

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

درك و فهم يك نوع شمارشي يا يك 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);
    }
}

 

نظرات برای این نوشته

A Man


متن نظر :

Finindg this post has solved my problem.