۱۰-بهمن-۱۳۹۲, ۱۶:۵۱:۰۰
انواع شمارشي در 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 در حالت كلي بصورت زير است :
در مثال 1-17 كه در زير ملاحظه ميكنيد، نحوه اعلان و استفاده از enum مشخص شده است.
مثال 1-17 : نحوه اعلان يك enum
در مثال 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 را تغيير داد. به مثال زير توجه كنيد.
همنطور كه مشاهده ميشود، در اعلان اول، از مقدار پيش فرض استفاده شده، كه در اين حالت 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 پایه و تخصیص دهی اعضای آن
با توجه به مثال 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
ساخت يك نوع شمارشي جديد
چگونگي استفاده از انواع شمارشي
آشنايي با متدهاي مختلف موجود در 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 در حالت كلي بصورت زير است :
کد:
enum
{
// 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
}
هر چند به تمامي عناصر 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();
}
}
همانطور که قبلا نیز اشاره شد، مقدار پیش فرض برای اولین عضو 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 {
Console.WriteLine(i + "." + langAr[i]);
}
Language myLang=(Language)Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your Language of choice is: " + myLang);
}
}